实际上,您的检测可能是错误的。
问题是您所检测到的只是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++ 中推荐的方法是尽可能不要使用特征;例如,在函数中,您可以decltype
在类型签名中使用 right 。