我有一个对象数据库,并且想在编译时计算有多少个对象属于特定类型,但在编译时遇到了一些麻烦。
这是我迄今为止一直在尝试的一个精简示例,但是无法编译,并显示“错误:调用函数'do_count',该函数在模板定义中既不可见,也不能通过参数相关的查找找到”
有更好的方法吗?
#include <cstdint>
#include <type_traits>
#include <cstddef>
struct unused_tag {};
struct used_tag {};
template<std::size_t X>
struct traits {
using type = unused_tag;
};
template<>
struct traits<7> {
using type = used_tag;
};
static constexpr const std::size_t MAX_X = 10;
template<std::size_t X = 0>
constexpr
std::enable_if_t<
!std::is_same<typename traits<X>::type, unused_tag>::value,
std::size_t>
do_count()
{
return do_count<X + 1>() + 1;
}
template<std::size_t X = 0>
constexpr
std::enable_if_t<
std::is_same<typename traits<X>::type, unused_tag>::value,
std::size_t>
do_count()
{
return do_count<X + 1>();
}
template<>
constexpr std::size_t do_count<MAX_X>()
{
return 0;
}
static constexpr const std::size_t COUNT = do_count();
最佳答案
您似乎找到了解决问题的不同解决方案,但如果您好奇的话,这里有一个使用 std::enable_if 的解决方案。
问题是从 !std::is_same<...> 版本调用 do_count 无法看到 std::is_same<...> 版本,因此,正如编译器所说,从调用现场也无法解决。要解决此问题,只需对 std::is_same<...> 进行前向声明即可。
对于您的示例,我可以编译以下内容:
#include <cstdint>
#include <type_traits>
#include <cstddef>
struct unused_tag {};
struct used_tag {};
template<std::size_t X>
struct traits {
using type = unused_tag;
};
template<>
struct traits<9> {
using type = used_tag;
};
static constexpr const std::size_t MAX_X = 10;
//
// forward declaration
//
template<std::size_t X = 0>
constexpr
std::enable_if_t<
std::is_same<typename traits<X>::type, unused_tag>::value,
std::size_t>
do_count();
template<std::size_t X = 0>
constexpr
std::enable_if_t<
!std::is_same<typename traits<X>::type, unused_tag>::value,
std::size_t>
do_count()
{
return do_count<X + 1>() + 1;
}
template<std::size_t X>
constexpr
std::enable_if_t<
std::is_same<typename traits<X>::type, unused_tag>::value,
std::size_t>
do_count()
{
return do_count<X + 1>();
}
template<>
constexpr std::size_t do_count<MAX_X>()
{
return 0;
}
static constexpr const std::size_t COUNT = do_count();
关于c++ - 如何根据类型特征进行 constexpr 计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41275439/