9

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?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Oliv
  • 17,610
  • 1
  • 29
  • 72
  • I was certain of my answer, until I read further to [temp.dep.candidate-1.2](https://timsong-cpp.github.io/cppwp/n4659/temp.dep.res#temp.dep.candidate-1.2). IIUC, that means you are correct. And `A::f` should not be found. What compilers did you try? – StoryTeller - Unslander Monica Jul 22 '18 at 13:08
  • @StoryTeller I tried gcc and clang: [compiler explorer](https://godbolt.org/g/ca4Brz) – Oliv Jul 22 '18 at 13:09
  • @StoryTeller So I include this paragraph in the question. Still the answer you have deleted was clever, it may be was the intent of this paragraph. – Oliv Jul 22 '18 at 13:15
  • Maybe it was. But that paragraph is pretty clear too. I think Clang and GCC are just falling back to the whole violation issue being ill-formed NDR. I'm not sure anymore :) – StoryTeller - Unslander Monica Jul 22 '18 at 13:19
  • @StoryTeller What NDR requirement might apply here? The quoted paragraphs don't say NDR, and failure to find any candidate functions / a best viable function normally requires a diagnostic. – aschepler Jul 22 '18 at 14:23
  • @aschepler - The NDR outlined in the following (not shown here) [temp.point] paragraphs. If template instantiations would have different meanings in different TU's, that's ill-formed NDR. And that's what I think Clang and GCC are (erroneously) implementing here, instead of diagnosing a missing candidate. I know it's not NDR, I brought the second paragraph to Oliv's attention. – StoryTeller - Unslander Monica Jul 22 '18 at 14:29

1 Answers1

9

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.

Community
  • 1
  • 1
Columbo
  • 60,038
  • 8
  • 155
  • 203
  • Glad to ear that, I was wondering if I had to include library headers after declarations of static functions in implementation files! – Oliv Jul 22 '18 at 15:08