Je suis en train de résoudre un problème classique: vérifier s'il existe une fonction libre dans un espace de noms. Il est discuté, par exemple, here.Méta-programmation de modèle: vérification de l'existence d'une fonction définie plus tard
Cependant, il y a une légère torsion: la définition de la fonction peut apparaître plus tard que la classe de vérificateur. Voici un exemple.
struct Yes {};
struct No {};
struct YesButLater {};
void f(Yes) {}
template<typename T, typename Enable = void>
struct HasF : public std::false_type {};
template<typename T>
struct HasF<T, decltype(void(::f(T())))> : public std::true_type {};
void f(YesButLater) {}
int main() {
cout << HasF<Yes>::value << endl; // 1
cout << HasF<No>::value << endl; // 0
cout << HasF<YesButLater>::value << endl; // 0, expected 1
}
f(YesButLater)
est déclaré plus tard que HasF
classe d'aide, et, bien que j'instancier le modèle après f(YesButLater)
a été défini, l'aide ne remarque pas. Donc, voici la question 1: comment puis-je m'en occuper?
Maintenant, un exemple de plus, plus curieux.
template<typename T>
struct HasF<T, decltype(void(f(T())))> : public std::true_type {};
void f(YesButLater) {}
void f(std::string) {}
int main() {
cout << HasF<YesButLater>::value << endl; // 1 (but what's the difference?)
cout << HasF<std::string>::value << endl; // 0, expected 1
}
Notez que j'ai enlevé ::
de l'expression decltype(...)
. Maintenant, pour une raison quelconque f(YesButLater)
est noté par HasF
, mais f(std::string)
reste encore obscur.
Question 2: Pourquoi observons-nous un comportement différent pour ::f(T())
et f(T())
dans cet exemple? De plus, quelle est la différence entre YesButLater
et std::string
?
Je pense qu'il y a un truc avec la recherche d'espace de noms mais je ne peux pas obtenir la chose.
je pense - elle est due à [adl] règles (...) http://en.cppreference.com/w/cpp/language/adl –
@ W.F. Oui, sans doute, mais je ne comprends toujours pas pourquoi :: les questions que je toujours utiliser espace de noms global dans l'exemple. –