eXX*_*XX2 5 c++ templates sfinae template-specialization c++11
我正在尝试实现一种机制来检测提供的类是否包含某些静态方法。这是非常简单的代码,但我无法理解为什么decltype()不能按EnableIfHasFooMethod类专业化的预期工作:
#include <iostream>
struct A {
static int Foo() { return 0; }
};
template <class T, class = void>
struct EnableIfHasFooMethod {};
template <class T>
struct EnableIfHasFooMethod<T, decltype(T::Foo)> {
typedef void type;
};
template <class T, class = void>
struct HasFooMethod {
static const bool value = false;
};
template <class T>
struct HasFooMethod<T, typename EnableIfHasFooMethod<T>::type> {
static const bool value = true;
};
int main() {
std::cout << HasFooMethod<A>::value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是0,但应该是1。
你忘记添加void()
template <class T>
struct EnableIfHasFooMethod<T, decltype(T::Foo, void())> { /* ... */ };
// ...........................................^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
您需要匹配第二个类型 ( void)
// ........................vvvv
template <class T, class = void>
struct EnableIfHasFooMethod {};
Run Code Online (Sandbox Code Playgroud)
所以你decltype()必须返回void当且仅当(当且仅当) 中有一个Foo()成员T。
你不能写
decltype( T::Foo )
Run Code Online (Sandbox Code Playgroud)
因为,在这种情况下,返回不能是的decltype()成员(如果存在)的类型。Foovoid
你不能写
decltype( void() )
Run Code Online (Sandbox Code Playgroud)
因为,在这种情况下,decltype()返回ever void,但你想要它,当且仅当有一个Foo成员在T
所以解决办法是
decltype( T::Foo , void() )
Run Code Online (Sandbox Code Playgroud)
所以 SFINAE 可以工作,如果不存在成员,则替换失败,如果有则Foo返回。voidFoo
| 归档时间: |
|
| 查看次数: |
976 次 |
| 最近记录: |