Name Resolution and Creation Point in Templates

This statement is from ISO C ++ 14.6.4.1. Instance Point

4.If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization. 5.An explicit instantiation directive is an instantiation point for the specialization or specializations specified by the explicit instantiation directive. 6.The instantiation context of an expression that depends on the template arguments is the set of declarations with external linkage declared prior to the point of instantiation of the template specialization in the same translation unit. 

I can not write programs for this entire section. I have been trying to write programs for this section since yesterday.

Please, usually I will try to set 1 or more points. In any section. But here I can not understand a single point in this section.

So, kindly can someone provide me with code to understand these sections.

0
source share
2 answers

The first two statements explain where the point of creation of specific template structures; he does not introduce new template designs. This way you can reuse your previous examples.

The third statement (14.6.4.1/6) states that the point of instantiation points: this is the point where names are looked up during the second phase of the name search. Names declared to the point of creation are visible; those subsequently announced are not. (In the first phase of searching for two-phase names, independent names are looked up in the set of declarations that precede the template definition).

So, considering:

 template <typename T> void foo() { T() + T(); } 

expression expression contexts T()+T() is the set of declarations preceding the corresponding creation points foo<T> . The name operator+ looked up in these contexts and includes declarations that follow this definition but precede the instantiation point.

+2
source

There always seem to be a lot of questions regarding the context of creation.

The example given by MSalters is problematic:

 template <typename T> void foo() { T() + T(); } 

consider the following code:

 #include <iostream> using namespace std; template <typename T> void foo() { T() + T(); } class A {}; void operator +(const A&, const A&) { cout << "Called operator+(const A&, const A&)" <<endl; } int main() { foo<A>(); } 

This compiles and runs on all compilers, but if you put the definition of class A in the namespace:

 #include <iostream> using namespace std; template <typename T> void foo() { T() + T(); } namespace { class A {}; } void operator+(const A&, const A&) { cout << "operator+(const N::A&, const N::A&)" << endl; } int main() { foo<A>(); } 

Clang will not be able to compile, but compiling VC ++ and gcc. What for? Which compiler complies with the specification?

Honestly, I do not know. Some compilers, such as gcc, even contradict themselves in this area. Consider the following code:

 #include <iostream> using namespace std; template <typename T> void foo() { g(T()); } namespace { class A {}; } void g(A a) { cout << "g(A)" << endl; } int main() { foo<A>(); } 

Just change from "operator +" to a function named "g", gcc will not compile ??? Why???

If Spec is correct, then why can't GCC find 'g'?

6. The context for creating an expression, which depends on the arguments of the template, is a set of declarations with an external link declared before the creation of the template
specialization in the same translation unit.

When I read Bjarne Stroustrup "C ++ Programming Language, 4th Edition", 26.3.5 Template and Namespaces, it has this example:

 namespace N{ class A{}; char f(A); } char f(int); template<typename T> char g(T t) { return f(t); //choose f() depending on what T is } char f(double); char c1 = g(N::A()); //causes N::f(N::A) to be called char c2 = g(2); //causes f(int) to be called char c3 = g(2.1); //causes f(int) to be called, f(double) not considered 

Here f (t) clearly depends, therefore, we cannot bind f at the definition point. To generate a specialization for g (N :: A), the compiler looks up the N namespace for functions called f () and fins N :: f (N :: A).

F (int) is found because it is in scope at the template definition point. F (double) was not found because it is not in the scope of the point in the template, and the argument-dependent search does not find that the global function accepts only arguments of built-in types.

So this is a mess!

+1
source

All Articles