Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An issue about instantiation context

Consider the following example in module.context p7

//Translation unit #1:

export module stuff;
export template<typename T, typename U> void foo(T, U u) { auto v = u; }
export template<typename T, typename U> void bar(T, U u) { auto v = *u; }  

//Translation unit #2:

export module M1;
import "defn.h";        // provides struct X {};
import stuff;
export template<typename T> void f(T t) {
  X x;
  foo(t, x);
}

// Translation unit #3:

export module M2;
import "decl.h";        // provides struct X; (not a definition)
import stuff;
export template<typename T> void g(T t) {
  X *x;
  bar(t, x);
}

// Translation unit #4:

import M1;
import M2;
void test() {
  f(0);
  g(0);
}

For f(0), the comment says that

the instantiation context of foo<int, X> comprises

  • the point at the end of translation unit #1,
  • the point at the end of translation unit #2, and
  • the point of the call to f(0),

I can understand the first point, because of this rule

During the implicit instantiation of a template whose point of instantiation is specified as that of an enclosing specialization ([temp.point]), the instantiation context is the union of the instantiation context of the enclosing specialization and, if the template is defined in a module interface unit of a module M and the point of instantiation is not in a module interface unit of M, the point at the end of the declaration-seq of the primary module interface unit of M (prior to the private-module-fragment, if any).

However, I cannot figure out the remaining points, especially the second one. How to interpret such two points?

UPDATE:

From the answers of @Nicol Bolas

So "the instantiation context of the enclosing specialization" of foo is the instantiation context of f. Which includes the end of TU2, pursuant to what you quoted and emphasized.

I don't think the emphasized wording says the instantiation context of the enclosing specialization comprises "the end of TU2". I think the whole [module.context#3] should be parsed as that

During the implicit instantiation of a template T whose point of instantiation is specified as that of an enclosing specialization ([temp.point]), the instantiation context is the union of the instantiation context of the enclosing specialization and, if the template T is defined in a module interface unit of a module M and the point of instantiation is not in a module interface unit of M, the point at the end of the declaration-seq of the primary module interface unit of M (prior to the private-module-fragment, if any).

The template T does not designate the template from which the enclosing specialization is instantiated.

like image 589
xmh0511 Avatar asked Sep 29 '21 06:09

xmh0511


1 Answers

All of this goes back to what you quoted but didn't follow the link on: "enclosing specialization". From [temp.point]/1:

For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization.

In TU2, the function template foo is specialized within the function template f. f is the "enclosing specialization" of foo.

So "the instantiation context of the enclosing specialization" of foo is the instantiation context of f. Which includes the end of TU2, pursuant to what you quoted and emphasized.

As for the third point... it's just the second point repeated for the use of f. f(0) specializes f, thereby acting as part of its instantiation context. Because foo is enclosed within f, this also acts as part of the instantiation context for foo.

like image 142
Nicol Bolas Avatar answered Oct 20 '22 20:10

Nicol Bolas