使用SFINAE检测成员函数
Using SFINAE to detect a member function
在C++11中,要确定类是否具有成员函数size
,可以定义以下测试助手:
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中,在不依赖typeof
之类的编译器扩展的情况下,有类似的技巧吗?
实际上,您的检测可能是错误的。
问题是,您检测到的只是C
有一个成员size
:
- 它可能是一个属性
- 它可以是一个具有任何签名的方法
- 甚至可能有几种方法(具有各种签名)
如果您希望加强检测,则应尝试仅检测右侧size
(无论右侧是什么)。这里是这样一个硬化的检测。
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);
};
编辑:带有过载。
处理不正确的size
成员的诀窍是really_has
结构。我并不假装它是完美的,尽管。。。
在C++11中,事情更简单(尽管同样冗长),因为您可以通过直接使用来检测事情。因此,等效特性是:
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++中推荐的方法是如果可以的话,不要使用traits;例如,在函数中,您可以在类型签名中使用decltype
权限。
相关文章:
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针