簡體   English   中英

如何基於類型特征進行constexpr計數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM