(本题与C++11/C++14无关:示例使用C++03编译)
enable_bool<T>
有成员(member)::type
仅当 T
是bool
template <class T>
struct enable_bool
{};
template <>
struct enable_bool< bool >
{ typedef bool type; };
在下一个片段中,部分特化是正确的(参见 gcc.godbolt.org )
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
和 Enable
.
但是编译器提示(参见 gcc.godbolt.org )
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; }
};
为什么编译器无法推导出模板参数 T
在上述部分特化中?
最佳答案
最后这个问题甚至与 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
=> 无法推断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
意味着默认情况下第三个参数与第一个参数相同)
固定片段:
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();
}
关于c++ - 为什么 SFINAE 需要 'Enable' 类模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32998062/