Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么成员检测器回退必须是int?_C++_Sfinae - Fatal编程技术网

C++ 为什么成员检测器回退必须是int?

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

我想我是从这里得到了这个课程的想法:

但是,无论是否有MyTest成员,检测器都会为所有类返回“true”。我把线路改成:

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>;