views:

123

answers:

1

Is it possible to write an impure template in C++? That is, a template that will sometimes give a different resulting type or int for the same template parameters. For example, is it possible to write a template Foo<T> where Foo<int>::type is sometimes char and at other times float? Or a template Foo<T> where Foo<double>::my_static_const_int is sometimes 10 and other times 20?

+8  A: 

It's not possible. If you have a template that behaves that way, it violates the ODR and / or other rules, such as that a specialization should be declared before it would be instantiated. So you can't just put a specialization that would somehow change a typedef member to make it resolve to a different type for all following references.

Remember that Foo<T> references a class if Foo is a class template. If the class's typedef member is defined to be one type at one point in the program, and another type at another point, then something must have been gone wrong. Here are various Standard quotes that concern this


A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit. A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple translation units. If two different points of instantiation give a template specialization different meanings according to the one definition rule (3.2), the program is ill-formed, no diagnostic required.


If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.


(Various "noise" skipped)

[..Various entities that may be defined multiple in the whole program..]. 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;
  • 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)...
  • 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.
Johannes Schaub - litb
(Various "noise" skipped) - I like that! :)
Richard Corden