9
votes

According to the C++17 standard, [temp.point]/4, emphasis mine,

For a class template specialization, a class member template specialization, or a specialization for a class member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization, if the context from which the specialization is referenced depends on a template parameter, and if the specialization is not instantiated previous to the instantiation of the enclosing template, the point of instantiation is immediately before the point of instantiation of the enclosing template. Otherwise, the point of instantiation for such a specialization immediately precedes the namespace scope declaration or definition that refers to the specialization.

I don't understand how to interpret this sentence. Elsewhere, when describing name lookup in templates, the standard refers to the "instantiation context" and the "definition context". There, the word "context" seems to mean a particular point in the source text, which determines the set of visible names. Here, I'm not sure if the meaning of "context" is the same. If that is what it means, I'm not sure what it means for it to depend on a template parameter. Does that mean it's inside a template, or does it specifically mean there are still some unbound template parameters from enclosing templates at the point where the compiler decides to instantiate the specialization in question, or something else?

Examples would be appreciated.

3

3 Answers

4
votes

This context appears inside an enclosing template (from within another template specialization and depends on a template parameter). It must depends on a template parameter of the enclosing template, so it may be a context inside the definition context of the enclosing template.

So I suppose this paragraph could be illustrated by this example:

template<class T> struct A{};
template<class T> struct B{};

//point of instantiation of B<int>
template<class T> void f(){
   A<T> a;    //The context depends on enclosing template parameter T
   B<int> b;  //The context does not depend on a template parameter.
   }
//
void g(){
  f<double>();
  }
//point of instantiation of A<double>
//point of instantiation of f<double>
0
votes

[This is really more of an extended comment on @Oliv's answer than an answer in itself.]

[temp.point] is a sub-section of [temp.dep.res], which is "Dependent name resolution".

The point here is that I might have something on this order:

template <class T>
class foo { 
    using name = int;
};

template <>
class foo<float> {
    using name = long;
};

template <class T>
class bar {
   foo<typename T> f; // Point A
};

At point A, the meaning of f::name depends on the T over which bar was instantiated, because instantiating foo over int uses the specialization of foo.

At least as I read things, that's the context (pardon still more overloading of the term) in which the paragraph in question is intended to mean something.

0
votes

"Instantiation context" refers to the point in source code where the instantiation occurs. The standard is defining where that point is for each scenario of instantiation, hence the name "point of instantiation".

The words "context" and "depend" are used colloquially to mean what they mean in English, ie "place in source code" and "determined by" respectively. So necessarily, the construct has to appear inside a template (aka "the context from which the specialization is referenced") in order to depend on some template parameter.

template<typename> struct A {};

// Point of instantiation for A<int>
template<typename T>
struct B
{
    A<int> a1;
    A<T>   a2;  // Depends on T
};

// Point of instantiation for A<char>
// Point of instantiation for B<char>
void foo()
{
    B<char> b;
}

The point (pardon the pun) of such a definition is to define the behaviour of any construct depending on the completeness of a class at a particular point in source code. The rules are deceptively complicated, a case where it matters is Is stateful metaprogramming ill-formed (yet)?