问题描述
在C ++ 11中,要确定一个类是否具有成员函数 size
,可以定义以下测试助手:
In C++11, to find out whether a class has a member function size
, you could define the following test helper:
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
?
Is there a similar trick for doing this in C++98 without relying on compiler extensions such as typeof
?
推荐答案
实际上,您的检测有潜在的错误。
Actually, your detection is potentially erroneous.
问题是,您检测到的只是 C
的成员 size
:
The problem is that all you are detecting is that C
has a member size
:
- 它可以是一个属性
- 它可以是具有任何签名的方法
- 甚至可能有几种方法(具有各种签名)
如果您想变硬检测时,您应该尝试仅检测 right size
(无论什么权利)。 。
If you wish to harden the detection, you should attempt to detect only the right size
(for whatever right is). Here is such a hardened detection.
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
结构。
The trick to deal with incorrect size
members is the really_has
structure. I make no pretense that it is perfect, though...
在C ++ 11中,(尽管同样冗长),因为您可以直接通过使用来检测事物。因此,等效特征为:
In C++11, things are simpler (though no less verbose) because you can detect things by use directly. The equivalent trait is thus:
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
。
However, the recommended method in C++ is not to use traits if you can; in functions for example you can use decltype
right in the type signature.
这篇关于使用SFINAE检测成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!