Myślałam, że coraz ideę tej klasie (stąd https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector):Dlaczego funkcja wykrywania detektora członkowskiego musi być int?
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 };
};
ale starałem się dostosować go do mojego przypadku, w którym szukałem członka double MyTest
. Więc zmieniłem tę linię:
struct Fallback { int X; }; // add member name "X"
do
struct Fallback { double MyTest; };
ale detektor wracał „true” dla wszystkich klas niezależnie od tego, czy mieli człon MyTest czy nie. Zmieniłem linię na:
struct Fallback { int MyTest; };
, a następnie działało zgodnie z oczekiwaniami.
Czy ktoś może wyjaśnić, dlaczego awarię musi być int, a nie typ członka, którego faktycznie szukasz?
Oto przykład, gdzie szukać X jako int, ale Y jako podwójny:
#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;
}
Moja wyjścia:
Teraz rozumiem, że nie powinien mieć znaczenia, jaki to jest, ale nadal nie działa z "podwójnym" (zobacz mój przykład w mojej ostatniej edycji). –
@DavidDoria Ponieważ masz '& U :: X', gdzie musisz mieć' & U :: Y'. – Barry
Wow, masz na myśli, muszę wpisać właściwą rzecz dla kompilatora, aby wiedzieć, co chcę !? Przepraszamy za hałas ... –