(这个问题与C ++ 11 / C ++ 14无关:使用C ++ 03编译示例)
仅当IDictionary<long, IEnumerable<long, MyType>>
为enable_bool<T>
时, ::type
才会有T
成员
bool
在下一个代码段中,部分特化是正确的(请参阅gcc.godbolt.org)
template <class T>
struct enable_bool
{};
template <>
struct enable_bool< bool >
{ typedef bool type; };
由于template <class T, class U, class Enable = T>
struct Foo
{
static int bar() { return 0; }
};
template <class T, class U>
struct Foo< T, U, typename enable_bool<T>::type >
{
static int bar() { return 1; }
};
int main()
{
return Foo <int, bool>::bar();
}
已与enable_bool<T>::type
相对应(T
为T
时)
我们很想对参数bool
和T
进行分解
但编译器抱怨(见gcc.godbolt.org)
Enable
为什么编译器无法在上面的部分特化中推导出模板参数template <class T, class U>
struct Foo
{
static int bar() { return 0; }
};
template <class T, class U> //ERROR non-deducible template parameter 'T'
struct Foo< typename enable_bool<T>::type, U >
{
static int bar() { return 1; }
};
?
答案 0 :(得分:2)
最后这个问题甚至与SFINAE无关!
考虑一下没有SFINAE的这个非常简单的片段:
无论提供的enable<T>::type
类型是什么,T
始终与T
相同。
template <class T>
struct enable
{ typedef T type; }; // Enable always
template <class U, class V>
struct Foo
{
static int bar() { return 0; }
};
template <class X, class Y> //ERROR non-deducible parameter 'X'
struct Foo< typename enable<X>::type, Y >
{
static int bar() { return 1; }
};
int main()
{
return Foo<int, bool>::bar();
}
编译器尝试将Foo<int, bool>
与Foo<typename enable<X>::type,Y>
1st param U = int <--> enable<X>::type
=&gt;无法推断X
2nd param V = bool <--> Y
编译器的目的不是从等式X
推导出int = enable<X>::type
因此,编译器需要开发人员的帮助
需要另一个参数:Enable
。
下面的固定代码段添加了Enable
类模板参数
编译器执行以下匹配:
1st param U =int <--> X
2nd param V =bool<--> Y
3rd param Enable=int <--> enable<X>::type
(从第一个参数中推断出X
)int
,因为声明class Enable=U
表示默认第3个参数与第1个相同 修正片段:
template <class T>
struct enable
{ typedef T type; }; // Enable always
template <class U, class V, class Enable = U>
struct Foo
{
static int bar() { return 0; }
};
template <class X, class Y> // Compiler can deduce 'X'
struct Foo< X, Y, typename enable<X>::type >
{
static int bar() { return 1; }
};
int main()
{
return Foo<int, bool>::bar();
}