Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c++ - Qualified friend function template instantiation

Looking at C++ Templates: The Complete Guide (2nd Edition)/official site this morning I came across a section I can't quite make sense out of (12.5.2 if you have the book). Omitting what seems irrelevant here:

If the name [in the friend declaration] is not followed by angle brackets there are two possibilities

  1. If the name isn't qualified [...]

  2. If the name is qualified (it contains ::), the name must refer to a previously declared function or function template. A matching function is preferred over a matching function template. However, such a friend declaration cannot be a definition.

With the following code

void multiply(void*);

template <typename T>
void multiply(T);

class Comrades {
    // ... skipping some friends that do not effect the error message
    friend void ::multiply(int); // refers to an instance of the template
    // ...
};

gcc error:

error: ‘void multiply(int)’ should have been declared inside ‘::’
     friend void ::multiply(int);
                               ^

clang error:

error: out-of-line declaration of 'multiply' does not match any
  declaration in the global namespace
friend void ::multiply(int);
              ^~~~~~~~

I'm trying to get to the bottom of this, and I've retyped the code a few times (though again if someone has the book...). Is the rule right and the compilers are wrong? Is the code not the right demonstration of the rule?

The complete code includes an earlier friend function definition:

class Comrades {
    friend void multiply(int) { }
    friend void ::multiply(int);
}

Which clang accepts and gcc rejects (that's a different question). In either case it doesn't demonstrate the rule that the author states, it's the second one referencing the earlier one in the same class.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The book is right. [temp.friend]p1 - with the relevant part highlighted:

For a friend function declaration that is not a template declaration:

  • if the name of the friend is a qualified or unqualified?template-id, [...]

  • if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, [...]

  • if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template

  • [...]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...