Reputation: 101
Consider the following example:
template <typename T>
class C
{
public:
friend void f() {}
friend void f(C<T>) {}
};
C<int> c;
void g(C<int>* p)
{
f();
f(*p);
}
Compiling with GCC 5.2 throws the following compile error:
no matching function for call to 'f()'
But the standard says in 14.6.5:
Friend classes or functions can be declared within a class template. When a template is instantiated, the names of its friends are treated as if the specialization had been explicitly declared at its point of instantiation.
Why does this fail to compile? In GCC 3.4, it passes.
Upvotes: 2
Views: 186
Reputation: 60979
f
can only be found via argument-dependent name lookup (ADL). The second call compiles because the pointee of p
, which is passed as an argument, is of type C<int>
- this causes ADL to jump in and inspect otherwise invisible functions. In fact, the first overload of f
can't be found at all, as there is no way of conveying an association to any specialization of C
.
Just see the quote right after yours, [temp.inject]/2:
As with non-template classes, the names of namespace-scope friend functions of a class template specialization are not visible during an ordinary lookup unless explicitly declared at namespace scope (11.3). Such names may be found under the rules for associated classes (3.4.2). 141
141) Friend declarations do not introduce new names into any scope, either when the template is declared or when it is instantiated.
Upvotes: 3
Reputation: 92261
The call to f()
is in no way associated with class C
, so its friends are not used in the overload resolution.
In the other call, f(*p)
, the parameter is of class type and therefore the class and the namespace of the class are checked for possible candidates. That way the compiler will find both f
functions and use overload resolution to select the proper one.
Upvotes: 1