我以为我得到了这个课程的想法(从这里https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector):
template<typename T>
class DetectX
{
struct Fallback { int X; }; // add member name "X"
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
typedef char ArrayOfOne[1]; // typedef for an array of size one.
typedef char ArrayOfTwo[2]; // typedef for an array of size two.
template<typename U>
static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
typedef DetectX type;
enum { value = sizeof(func<Derived>(0)) == 2 };
};
Run Code Online (Sandbox Code Playgroud)
但是我试着让它适应我正在寻找会员的情况double MyTest.所以我改变了这一行:
struct Fallback { int X; }; // add member name "X"
Run Code Online (Sandbox Code Playgroud)
至
struct Fallback { double MyTest; };
Run Code Online (Sandbox Code Playgroud)
但无论是否有MyTest成员,探测器都会为所有级别返回"true".我把线改为:
struct Fallback { int MyTest; };
Run Code Online (Sandbox Code Playgroud)
然后它按预期工作.
任何人都可以解释为什么后备必须是一个int而不是你实际上正在寻找的成员的类型?
这是一个例子,我将X视为int,而Y视为double:
#include <iostream>
#include <vector>
// https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector
// Standard point representation
struct Point3
{
double X,Y,Z;
};
struct SomethingElse{};
template<typename T>
class DetectX
{
struct Fallback { int X; }; // add member named "X"
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
typedef char ArrayOfOne[1]; // typedef for an array of size one.
typedef char ArrayOfTwo[2]; // typedef for an array of size two.
template<typename U>
static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
typedef DetectX type;
enum { value = sizeof(func<Derived>(0)) == 2 };
};
template<typename T>
class DetectY
{
struct Fallback { double Y; }; // add member named "Y"
struct Derived : T, Fallback { };
template<typename U, U> struct Check;
typedef char ArrayOfOne[1]; // typedef for an array of size one.
typedef char ArrayOfTwo[2]; // typedef for an array of size two.
template<typename U>
static ArrayOfOne & func(Check<double Fallback::*, &U::X> *);
template<typename U>
static ArrayOfTwo & func(...);
public:
typedef DetectY type;
enum { value = sizeof(func<Derived>(0)) == 2 };
};
int main()
{
std::cout << DetectX<Point3>::value << " " << DetectX<SomethingElse>::value << std::endl;
std::cout << DetectY<Point3>::value << " " << DetectY<SomethingElse>::value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的输出是:
1 0
1 1
不一定是这样int. It can be of any type. You just have to refer to it correctly, by type and name, in every place:
using Arbitrary = double;\n\nstruct Fallback { Arbitrary X; }; // <== arbitrary type, specific name X\nRun Code Online (Sandbox Code Playgroud)\n\n和 here:
\n\ntemplate<typename U> \nstatic ArrayOfOne & func(Check<Arbitrary Fallback::*, &U::X> *);\n// \xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\xe2\x86\x91 \xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\n// this type this name\nRun Code Online (Sandbox Code Playgroud)\n\n这个想法是,如果T没有X,您会找到Fallback::X,它将&U::X按类型匹配(因为只有一个 - 中的那个Fallback)。但如果T确实有X,则查找将不明确。所以什么类型并不重要Fallback::X-int只是最短的类型。
请注意,在 C++11 中,使用 Yakk\'s 之类的东西会更容易can_apply:
template <class T>\nusing x_type = decltype(&T::X);\n\ntemplate <class T>\nusing has_x = can_apply<x_type, T>;\nRun Code Online (Sandbox Code Playgroud)\n\n另请参阅此问题,了解其他六种比旧式成员检测器更好的方法。
\n