Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template dependent name resolution should not find declarations with no linkage?

In the c++ standard [temp.point] it is written:

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.

Then in [temp.dep.candidate]:

For the part of the lookup using associated namespaces ([basic.lookup.argdep]), only function declarations found in either the template definition context or the template instantiation context are found.

Does it means that the following code should fail:

namespace A{
    struct S{};
}

template<class T>
void g(T a){
    f(a); //f will be found by argument dependent lookup
}

namespace A{
    static void f(S); //but f doesn't have external linkage
}

void test(A::S i){
    g(i);
}
//point of instantiation of g
//A::f(S) doesn't have external linkage 
//=> so it's not in the instantiation context of template g ??

This code actually compiles, so what does this standard paragraph mean?

like image 216
Oliv Avatar asked Jul 22 '18 12:07

Oliv


1 Answers

This is a defect in the standard. Originally addressed in core issue 561, where the committee judged that

Notes from the April, 2006 meeting:

The consensus of the group was [..] that internal-linkage functions should be found by the lookup (although they may result in errors if selected by overload resolution).

Unfortunately the corresponding fix was insufficient, as elaborated in core issue 1258:

C++11 expanded the lookup rules for dependent function calls (17.7.4.2 [temp.dep.candidate] paragraph 1 bullet 2) to include functions with internal linkage; previously only functions with external linkage were considered. However, 17.7.4.1 [temp.point] paragraph 6 still says,

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.

Presumably this wording was overlooked and should be harmonized with the new specification.

That is, the previous wording of your second quoted paragraph was

For the part of the lookup using associated namespaces (3.4.2), only function declarations with external linkage found in either the template definition context or the template instantiation context are found.

.. which was amended for C++11, but that change missed your first quote, making it rather pointless. The intent is that functions with internal linkage are not discriminated.

like image 82
Columbo Avatar answered Nov 18 '22 16:11

Columbo