2011-09-27 11 views
1

私はenable_ifを使いこなしていましたが、私はいくつかの一貫性のない動作に遭遇したようです。これはVS2010にあります。私はそれを以下のサンプルに減らしました。std :: enable_if specialization failed

#include <type_traits> 

using namespace std; 

// enable_if in initial template definition 
template <class T, class Enable = enable_if<true>> struct foo {}; 

foo<int> a; //OK 

// explicit specialisation 
template <class T, class Enable = void> struct bar; 
template <class T> struct bar<T, void> {}; 

bar<int> b; //OK 

// enable_if based specialisation 
template <class T, class Enable = void> struct baz; 
template <class T> struct baz<T, std::enable_if<true>> {}; 

baz<int> c; //error C2079: 'c' uses undefined struct 'baz<T>' 

これはコードまたはコンパイラのバグですか?

答えて

3

あなたの問題はenable_if

// you declare a structure named baz which takes 2 template parameters, with void 
// as the default value of the second one. 
template <class T, class Enable = void> struct baz; 
// Partial specialization for a baz with T and an std::enable_if<true> 
template <class T> struct baz<T, std::enable_if<true>> {}; 

// Declare a baz<int, void> (remember the default parameter?): 
baz<int> c; //error C2079: 'c' uses undefined struct 'baz<T>' 

baz<int, void>その時点で不完全な型を持っているとはほとんど関係がありません。ジェームズが言ったように、あなたは間違ってenable_ifを使用している、

template <class T, class U = void> 
struct S; 

template <class T> 
struct S<T, int> 
{ }; 

S<double> s; 

そして:同じ問題がenable_ifせずに発生します。 Boost's documentation for enable_ifはそれを説明する素晴らしい仕事をします。

6

std::enable_if<true>は、typename std::enable_if<true>::typeである必要があります。

std::enable_if<true>は常にタイプを指定します(std::enable_if<false>と同じ)。条件がfalseのときに代入が失敗するには、条件が真である場合にのみ定義されるtypeネストされたtypedefを使用する必要があります。

+0

もちろん、ああ。ありがとう! – Ayjay

+0

@McNellis: "条件がfalseのときに代入が失敗するには、ネストされたtypedefを使用する必要があります。これは、条件がtrueの場合にのみ定義されます。" ...これは意味がありますか?それはあなたが失敗することは決してできないことを意味します。それはあなたが言っている意味ですか? –