[英]How to do a constexpr count based on a type trait
我有一個對象數據庫,想統計在編譯時有多少種特定類型的對象,但是在進行編譯時遇到了一些麻煩。
這是到目前為止我一直在嘗試的簡化示例,但這無法編譯為“錯誤:對函數'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();
事實證明,我為自己的利益太聰明了,就這么簡單:
#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_COUNT = 10;
template<std::size_t X = 0>
constexpr std::size_t do_count()
{
if (std::is_same<typename traits<X>::type, unused_tag>::value)
return 0 + do_count<X + 1>();
return 1 + do_count<X + 1>();
}
template<>
constexpr std::size_t do_count<MAX_COUNT>()
{
return 0;
}
static constexpr const std::size_t COUNT = do_count();
static_assert(COUNT == 1);
似乎您找到了解決問題的另一種方法,但是如果您好奇的話,這里是使用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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.