C++ 为什么成员检测器回退必须是int?
我想我是从这里得到了这个课程的想法: 到 但是,无论是否有MyTest成员,检测器都会为所有类返回“true”。我把线路改成:C++ 为什么成员检测器回退必须是int?,c++,sfinae,C++,Sfinae,我想我是从这里得到了这个课程的想法: 到 但是,无论是否有MyTest成员,检测器都会为所有类返回“true”。我把线路改成: struct Fallback { int MyTest; }; 然后它像预期的那样工作 有人能解释为什么回退必须是int而不是您实际寻找的成员类型吗 下面是一个示例,其中我将X视为int,而将Y视为double: #include <iostream> #include <vector> // https://en.wikibooks.or
struct Fallback { int MyTest; };
然后它像预期的那样工作
有人能解释为什么回退必须是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;
}
#包括
#包括
// https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector
//标准点表示法
结构点3
{
双X,Y,Z;
};
结构SomethingElse{};
模板
类检测器
{
结构回退{int X;};//添加名为“X”的成员
派生结构:T,回退{};
模板结构检查;
typedef char ArrayOfOne[1];//大小为1的数组的typedef。
typedef char ArrayOfTwo[2];//大小为2的数组的typedef。
模板
静态ArrayOfOne&func(检查*);
模板
静态数组wo&func(…);
公众:
typedef-tx型;
枚举{value=sizeof(func(0))==2};
};
模板
类检测
{
结构回退{double Y;};//添加名为“Y”的成员
派生结构:T,回退{};
模板结构检查;
typedef char ArrayOfOne[1];//大小为1的数组的typedef。
typedef char ArrayOfTwo[2];//大小为2的数组的typedef。
模板
静态ArrayOfOne&func(检查*);
模板
静态数组wo&func(…);
公众:
typedef检测类型;
枚举{value=sizeof(func(0))==2};
};
int main()
{
std::cout它不必是int
。它可以是任何类型。您只需在每个地方按类型和名称正确引用它:
using Arbitrary = double;
struct Fallback { Arbitrary X; }; // <== arbitrary type, specific name X
另请参阅六种比旧式成员检测器更好的其他方法。我现在明白,它是哪种类型并不重要,但它似乎仍然不能与“double”一起工作(请参阅我最近编辑的示例)@DavidDoria因为你有&U::X
你需要的&U::Y
。哇,你的意思是我必须键入正确的东西让编译器知道我想要什么!?对噪音感到抱歉…也许我发现了为什么这是一个糟糕的方法-我尝试了类X{};cout@DavidDoria,它被称为注入类名。
struct Fallback { int MyTest; };
#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;
}
using Arbitrary = double;
struct Fallback { Arbitrary X; }; // <== arbitrary type, specific name X
template<typename U>
static ArrayOfOne & func(Check<Arbitrary Fallback::*, &U::X> *);
// ↑↑↑↑↑↑↑↑↑↑ ↑↑↑
// this type this name
template <class T>
using x_type = decltype(&T::X);
template <class T>
using has_x = can_apply<x_type, T>;