Using SFINAE to detect a member function
本问题已经有最佳答案,请猛点这里访问。
在C++ 11中,为了找出一个类是否具有成员函数EDCOX1(0),可以定义以下测试助手:
1 2 3 4 5 6 7 8 9 10 11 | template <typename T> struct has_size_fn { typedef char (& yes)[1]; typedef char (& no)[2]; template <typename C> static yes check(decltype(&C::size)); template <typename> static no check(...); static bool const value = sizeof(check<T>(0)) == sizeof(yes); }; |
在C++ 98中是否有类似的技巧,而不依赖于编译器扩展,如EDCOX1?1?
实际上,您的检测可能是错误的。
问题是,您所检测到的只是
- 它可能是一个属性
- 它可以是一个带有任何签名的方法
- 甚至可能有几种方法(有各种签名)
如果你想加强检测,你应该试着只检测右边的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | template <typename T> class has_size { private: typedef char Yes; typedef Yes No[2]; template <typename U, U> struct really_has; template <typename C> static Yes& Test(really_has <size_t (C::*)() const, &C::size>*); // EDIT: and you can detect one of several overloads... by overloading :) template <typename C> static Yes& Test(really_has <size_t (C::*)(), &C::size>*); template <typename> static No& Test(...); public: static bool const value = sizeof(Test<T>(0)) == sizeof(Yes); }; |
编辑:带有重载。
对付不正确的
在C++ 11中,事情更简单(虽然不那么冗长),因为你可以通过直接使用来检测事物。因此,等效特性是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | template <typename T> class has_size { private: typedef char Yes; typedef Yes No[2]; template<typename C> static auto Test(void*) -> decltype(size_t{std::declval<C const>().size()}, Yes{}); template<typename> static No& Test(...); public: static bool const value = sizeof(Test<T>(0)) == sizeof(Yes); }; |
但是,C++中推荐的方法是不使用特性;如果在函数中,您可以在类型签名中使用EDCOX1(5)右。
对:
1 | char (*)[sizeof(&C::size)] |