Template Metaprogramming & branching
-
ergibt Sinn, danke
-
Kann man das nicht auch als
template< class WrapperParam > class XY { private: template<bool b, typename FunctionParam> class Helper { static void HelperFunc() { FunctionParam object2; } } template<typename FunctionParam> class Helper<false, FunctionParam> { static void HelperFunc() { } } public: template< class FunctionParam > void function() { Helper<is_complete_type< FunctionParam >::value>::HelperFunc(); } };regeln? So mit ohne Parameterübergabe
-
Das welchen Vorteil hätte?
-
314159265358979 schrieb:
Das welchen Vorteil hätte?
Den Parameter sparen, der wohl doch nur wegoptimiert werden kann, wenn die Funktion inline ist oder der Compiler link time code generation macht.
-
Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.
-
Cachus schrieb:
Kann man das nicht auch als
template< class WrapperParam > class XY { private: template<bool b, typename FunctionParam> class Helper { static void HelperFunc() { FunctionParam object2; } } template<typename FunctionParam> class Helper<false, FunctionParam> { static void HelperFunc() { } } public: template< class FunctionParam > void function() { Helper<is_complete_type< FunctionParam >::value>::HelperFunc(); } };regeln? So mit ohne Parameterübergabe
So hab ich das bis jetzt auch gemacht, aber das ganze ist ziemlich umständlich:
- Klasse definieren
- Zugriff auf member der Klasse ist kompliziert, man muss this pointer mit übergeben etc... ich finde 314s Lösung besser.
-
camper schrieb:
Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.
Weswegen das?
-
Nachgefragt... schrieb:
camper schrieb:
Diese Verwendung von is_complete dürfte ganz schnell zu einer ODR-Verletzung führen.
Weswegen das?
ISO 14882.2003 schrieb:
3.2 One definition rule [basic.def.odr]
...
5 There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.4) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then
— each definition of D shall consist of the same sequence of tokens; and
— in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a const object with internal or no linkage if the object has the same integral or enumeration type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D; and
— in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and
— in each definition of D, a default argument used by an (implicit or explicit) function call is treated as if its token sequence were present in the definition of D; that is, the default argument is subject to the three requirements described above (and, if the default argument has sub-expressions with default arguments, this requirement applies recursively).25)
— if D is a class with an implicitly-declared constructor (12.1), it is as if the constructor was implicitly defined in every translation unit where it is used, and the implicit definition in every translation unit shall call the same constructor for a base class or a class member of D. [Example:
...—end example] If D is a template, and is defined in more than one translation unit, then the last four requirements from the list above shall apply to names from the template’s enclosing scope used in the template definition (14.6.3), and also to dependent names at the point of instantiation (14.6.2). If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.Im Allgemeinen ist davon auszugehen, dass die betreffende Klasse irgendwo mal vollständig definiert wird. Sollte in der jeweiligen ÜE dann ein entsprechender Aufruf stehen, gibt es ein Problem.
-
ich sehe da jetzt kein Problem.
-
otze schrieb:
ich sehe da jetzt kein Problem.
z.B. in Pis Version
template <typename U> void function() { function<U>(bool_to_type<is_complete_type<T>::value>()); }Je nach Typ und Punkt der Instantiierung ist das entweder:
function<U>(bool_to_type<true>())oder
function<U>(bool_to_type<false>())also völlig verschiedene Dinge. Die Abhängigkeit vom Instantiierungsort ist hier das Problem: Die ODR sagt klar, dass die Bedeutung an allen Instantiierungsorten gleich sein muss. Ist der Typ nun an einigen Instantiierungsstellen unvollständig, and anderen aber vollständig, so ist die ODR offenbar verletzt.
Grundsätzlich ist es gefährlich is_complete auf diese Weise einzusetzen. Meiner Ansicht nach ist das primär für compile-time assertions nützlich.