ho pensato che fosse l'idea di questa classe (da qui https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector):Perché il fallback di Member Detector deve essere 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 };
};
ma ho cercato di adattarlo al mio caso in cui ero alla ricerca di un membro double MyTest
. Così ho cambiato questa linea:
struct Fallback { int X; }; // add member name "X"
a
struct Fallback { double MyTest; };
ma il rilevatore tornavo "true" per tutte le classi a prescindere se avessero un membro Mytest o meno. Ho cambiato la riga in:
struct Fallback { int MyTest; };
e quindi ha funzionato come previsto.
Qualcuno può spiegare perché il fallback deve essere un int piuttosto che il tipo di membro che si sta effettivamente cercando?
Ecco un esempio in cui cerco X come un int, ma Y come una doppia:
#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;
}
La mia uscita è:
Ora ho capito che non dovrebbe importare quale tipo sia, ma ancora non sembra funzionare con 'double' (vedi il mio esempio nella mia recente modifica). –
@DavidDoria Perché hai '& U :: X' dove devi avere' & U :: Y'. – Barry
Wow, vuoi dire che devo scrivere la cosa giusta per il compilatore per sapere cosa voglio !? Scusa per il rumore ... –