2016-12-22 42 views
1

我有一個對象的數據庫,並且想在編譯時計算一個特定類型的數量,但是我在編譯時遇到了一些問題。如何根據類型特徵做一個constexpr計數

這裏是我迄今爲止一直在嘗試的一個簡化示例,但是這樣做無法用「error:call to function'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); 
相關問題