C++ 标准:德克瓦尔<;T>;()、SFINAE和已删除的构造函数
在C++11中使用SFINAE进行方法检测时,我编写了以下运行示例:C++ 标准:德克瓦尔<;T>;()、SFINAE和已删除的构造函数,c++,c++11,metaprogramming,sfinae,C++,C++11,Metaprogramming,Sfinae,在C++11中使用SFINAE进行方法检测时,我编写了以下运行示例: #include <type_traits> struct Foo { Foo();// = delete; Foo(int); void my_method(); }; template <typename T, typename ENABLE = void> struct Detect_My_Method : std::false_type { }; template &
#include <type_traits>
struct Foo
{
Foo();// = delete;
Foo(int);
void my_method();
};
template <typename T, typename ENABLE = void>
struct Detect_My_Method
: std::false_type
{
};
template <typename T>
struct Detect_My_Method<T, decltype(T().my_method())>
: std::true_type
{
};
int main()
{
static_assert(!Detect_My_Method<double>::value, "");
static_assert(Detect_My_Method<Foo>::value, "");
}
示例为不再工作,我收到以下错误消息:
g++ -std=c++11 declVal.cpp
declVal.cpp: In function ‘int main()’:
declVal.cpp:33:3: error: static assertion failed
static_assert(Detect_My_Method<Foo>::value, "");
g++-std=c++11 declVal.cpp
declVal.cpp:在函数“int main()”中:
declVal.cpp:33:3:错误:静态断言失败
静态断言(检测我的方法::值“”;
问题:解释以及如何解决?删除空构造函数时构造:
decltype(Foo().my_method());
不再有效,编译器会立即投诉
error: use of deleted function ‘Foo::Foo()’
一个解决办法是使用
将任何类型T转换为引用类型,从而可以使用
decltype表达式中的成员函数,无需转到
通过构造函数
因此,取代:
template <typename T>
struct Detect_My_Method<T, decltype(T().my_method())>
: std::true_type
{
};
模板
struct Detect\u My\u方法
:std::true\u类型
{
};
借
模板
struct Detect\u My\u方法
:std::true\u类型
{
};
解决了这个问题
经验教训:
decltype(Foo().my_method()); // invalid
decltype(std::declval<Foo>().my_method()); // fine
decltype(Foo().my_method());//无效的
decltype(std::declval().my_method());//好的
不等效。删除空构造函数时构造:
decltype(Foo().my_method());
不再有效,编译器会立即投诉
error: use of deleted function ‘Foo::Foo()’
一个解决办法是使用
将任何类型T转换为引用类型,从而可以使用
decltype表达式中的成员函数,无需转到
通过构造函数
因此,取代:
template <typename T>
struct Detect_My_Method<T, decltype(T().my_method())>
: std::true_type
{
};
模板
struct Detect\u My\u方法
:std::true\u类型
{
};
借
模板
struct Detect\u My\u方法
:std::true\u类型
{
};
解决了这个问题
经验教训:
decltype(Foo().my_method()); // invalid
decltype(std::declval<Foo>().my_method()); // fine
decltype(Foo().my_method());//无效的
decltype(std::declval().my_method());//好的
不等效。此外,还有另一种定义测试的方法,既不需要指向对象的引用或指针,也不需要函数的特定签名:
template<class T>
typename std::is_member_function_pointer<decltype(&T::my_method)>::type test_member_function_my_method(int);
template<class T>
std::false_type test_member_function_my_method(...);
template<class T>
using has_member_function_my_method = decltype(test_member_function_my_method<T>(0));
模板
typename std::is_member_function_pointer::type test_member_function_my_method(int);
样板
std::false_类型测试_成员_函数_my_方法(…);
样板
使用has_member_function_my_method=decltype(test_member_function_my_method(0));
用法:
static_assert(!has_member_function_my_method<double>::value, "");
static_assert(has_member_function_my_method<Foo>::value, "");
static_assert(!has_member_function_my_method::value,”);
静态\u断言(具有\u成员\u函数\u我的\u方法::值“”);
此外,还有另一种定义测试的方法,既不需要指向对象的引用或指针,也不需要函数的特定签名:
template<class T>
typename std::is_member_function_pointer<decltype(&T::my_method)>::type test_member_function_my_method(int);
template<class T>
std::false_type test_member_function_my_method(...);
template<class T>
using has_member_function_my_method = decltype(test_member_function_my_method<T>(0));
模板
typename std::is_member_function_pointer::type test_member_function_my_method(int);
样板
std::false_类型测试_成员_函数_my_方法(…);
样板
使用has_member_function_my_method=decltype(test_member_function_my_method(0));
用法:
static_assert(!has_member_function_my_method<double>::value, "");
static_assert(has_member_function_my_method<Foo>::value, "");
static_assert(!has_member_function_my_method::value,”);
静态\u断言(具有\u成员\u函数\u我的\u方法::值“”);
这并不完全等同,因为declval
方法可以检测函数对象。如果T
具有成员变量my\u method
和运算符()
,它将检测到该变量有效。这可能是可取的,也可能不是可取的,也可能是你不在乎的。@Justin你说得对。它也不处理重载函数,因为这里不涉及调用参数。这并不完全等效,因为declval
方法可以检测函数对象。如果T
具有成员变量my\u method
和运算符()
,它将检测到该变量有效。这可能是可取的,也可能不是可取的,也可能是你不在乎的。@Justin你说得对。它也不处理重载函数,因为这里不涉及调用参数。