J'ai besoin d'un trait de type qui sera vrai si le type donné dérive de quelque chose, et faux sinon.
Par exemple:
template<class T>
struct is_inherit
//... logic of inheritance detection
;
template<class T>
void AppLogic(){
if constexpr(is_inherit<T>::value) {
puts("T has base");
//...
} else {
puts("T doesn't have base");
//...
}
}
struct A {};
struct C {};
struct B: C {};
int main() {
AppLogic<A>(); // print: T doesn't have base
AppLogic<B>(); // print: T has base
}
Est-il possible d'implémenter d'une manière ou d'une autre cette structure de trait "is_inherit"?
Pourquoi?
Je développe un constructeur de cadre de pile manuel pour Windows x64. Selon la documentation https://docs.Microsoft.com/en-us/cpp/build/return-values-cpp , si un type:
alors sa valeur de retour est dans le registre RAX, sinon la fonction a un argument caché que je dois détecter et gérer.
Auparavant, c'était la définition d'un POD C++ 03, mais en C++ 11, cela a changé:
Étant donné que la définition a changé dans la norme C++ 11, nous vous déconseillons d'utiliser
std::is_pod
pour ce test.
Jusqu'à présent, avec certains traits conjugués, je pouvais détecter si le type répondait ou non à la définition d'un POD C++ 03. Cependant, avec C++ 17, les règles d'agrégation ont changé, ce qui a brisé ma solution.
Si je peux en quelque sorte détecter si un type T a une classe de base, ma solution fonctionnera à nouveau.
Oui, c'est possible, du moins pour les agrégats.
Nous construisons d'abord un modèle de classe qui est convertible en n'importe quelle base appropriée de son paramètre de modèle:
template<class T>
struct any_base {
operator T() = delete;
template<class U, class = std::enable_if_t<std::is_base_of_v<U, T>>> operator U();
};
Ensuite, nous détectons si un paramètre de modèle T
est constructible agrégé à partir d'une valeur de type any_base<T>
:
template<class, class = void> struct has_any_base : std::false_type {};
template<class T>
struct has_any_base<T, std::void_t<decltype(T{any_base<T>{}})>> : std::true_type {};
Exemple .
Je crois que vérifier si "T
dérive de quoi que ce soit" n'est pas possible, du moins pas de manière conforme aux normes. Si vous utilisez cette technique pour vérifier si un type est ou non un POD/trivial/agrégat, certains traits de type peuvent vous aider: