Template in Liste suchen
-
Hallo da!
Abends spiele ich ja gerne mal mit templates herum, nun wollte ich schauen, ob ich herausfinden kann, ob ein Typ ein bestimmtes Template ist.
Bevor ich den Code poste, hier schon einmal die Frage: Geht das nicht auch irgendwie einfacher?#include <iostream> using namespace std; namespace test { template< typename... T > struct type_list {}; template< template< typename... > class Template, typename... Arguments > type_list<Arguments...> deduce_template_arguments(Template<Arguments...>*); template< typename T > type_list<> deduce_template_arguments(T*); template< typename T > struct foo { using type = void; }; template< typename Instance, typename ArgList, template< typename... > class Template, typename EnableIf = void > struct is_same_template_intern : public std::false_type {}; template< typename Instance, typename... Args, template< typename... > class Template > struct is_same_template_intern<Instance, type_list<Args...>, Template, typename foo<Template<Args...>>::type > : public std::conditional< std::is_same< Instance, Template<Args...> >::value, std::true_type, std::false_type >::type {}; template< typename Instance, template< typename... > class Template > struct is_same_template : public is_same_template_intern< Instance, decltype(deduce_template_arguments((Instance*)nullptr)), Template > {}; } template< typename T > struct test_struct { }; template< typename T1, typename T2 > struct test_struct2 { }; int main() { std::cout << test::is_same_template< test_struct<int>, test_struct >::value << "\n"; std::cout << test::is_same_template< test_struct2<int,int>, test_struct >::value << "\n"; std::cout << test::is_same_template< test_struct<int>, test_struct2 >::value << "\n"; std::cout << test::is_same_template< test_struct2<int, int>, test_struct2 >::value << "\n"; return 0; }
-
ob ein Typ ein bestimmtes Template ist.
Du meinst, ob ein Typ eine Spezialisierung eines Templates ist. Das geht so:
#include <iostream> template<typename T, template<typename...> class C> struct is_specialization : std::false_type {}; template<template<typename...> class C, typename... Args> struct is_specialization<C<Args...>, C> : std::true_type {}; template< typename T > struct test_struct{}; template< typename T1, typename T2 > struct test_struct2 {}; int main() { static_assert( is_specialization<test_struct<int>, test_struct>::value, "" ); static_assert( !is_specialization<test_struct2<int, int>, test_struct>::value, "" ); static_assert( !is_specialization<test_struct<int>, test_struct2>::value, "" ); static_assert( is_specialization<test_struct2<int, int>, test_struct2>::value, "" ); }Allerdings ist das eine recht sinnlose Angelegenheit, da Templates drei verschiedene Arten von Parametern haben können, und das in allen Kombinationen. Daher lässt sich ein allgemeines Template dafür nicht schreiben.
-
#include <iostream> namespace test { struct yes_type { static const bool value = true; }; struct no_type { static const bool value = false; }; template<template<typename...> class Template, typename... Arguments> yes_type is_same_template_impl(Template<Arguments...>*); template<template<typename...> class Template> no_type is_same_template_impl(...); template<typename Instance, template< typename... > class Template> struct is_same_template : public decltype(is_same_template_impl<Template>((Instance*)0)) {}; } template< typename T > struct test_struct { }; template< typename T1, typename T2 > struct test_struct2 { }; int main() { std::cout << test::is_same_template< test_struct<int>, test_struct >::value << "\n"; std::cout << test::is_same_template< test_struct2<int,int>, test_struct >::value << "\n"; std::cout << test::is_same_template< test_struct<int>, test_struct2 >::value << "\n"; std::cout << test::is_same_template< test_struct2<int, int>, test_struct2 >::value << "\n"; std::cout << test::is_same_template< int, test_struct2 >::value << "\n"; return 0; }ARGH. Arcoth war schneller und hat auch noch die elegantere Lösung.
Naja, ich tröste mich damit dass ich kaum TMP mache, speziell mit C++ 11 nicht
-
Wahhhh, ich war der Meinung ich hätte das ausprobiert und der Compiler mochte nicht
Oder hatte ich die Regel von gestern angewandt, obwohl hier gar kein Literal involviert ist? hrmmm.
Danke, das ist natürlich viel eleganter!Ich brauch das nicht im Allgemeinen funktionabel, ich bastel mir hier nur gerade Options-Listen für Templates zusammen und in diese Liste klatscht man dann Options-Templates.
some_template< Foo, list<some_option<Arg1, Arg2>, other_option<Arg3>> > foo;Das some_template-Template fischt sich dann einfach die Argumente aus der Options-Liste "get_nth_arg< List, some_option, 2, default_type>".