2016-12-22 8 views
1

私はオブジェクトのデータベースを持っていて、コンパイル時に特定の型の数を数えたいと思いますが、これをコンパイルするのに少し問題があります。タイプ特性に基づいてconstexprカウントを行う方法

ここまでは私がこれまで試みてきたものの例を示していますが、これは "エラー:関数 '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(); 
+1

は、この「データベース」のように何を求めていますか?あなたはいくつかの望ましい入力と出力の例について、より良い説明を提供できますか?そのエラーは何行ですか? – qxz

答えて

0

それはあなたの問題に異なる解決策を見つけたように思えるが、ここで使用したソリューションです。興味がある場合は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(); 
0

が、それはこのような単純なのですアウト私は自分の利益のためにあまりにもスマートされていたターン:

#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); 
関連する問題