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
297 views
in Technique[技术] by (71.8m points)

c++ - Friend function declaration/definition inside a namespace

Consider a class inside a namespace. The definition of the class declares a friend function.

namespace Foo
{
    class Bar
    {
        friend void baz();
    };
}

This should, based on what I know, declare baz() as a member of the innermost enclosing namespace, i.e. Foo.

Therefore, I expected the following definition for baz() to be correct:

void Foo::baz() { }

However, GCC (4.7) gives me an error.

error: ‘void Foo::baz()’ should have been declared inside ‘Foo’

Several solutions seem to work:

  • Declare baz() outside the class.

    namespace Foo
    {
        void baz();
    
        class Bar
        {
            friend void baz();
        };
    }
    
  • Define baz() inside the namespace.

    namespace Foo
    {
        class Bar
        {
            friend void baz();
        };
    }
    ...
    namespace Foo
    {
        void baz() { }
    }
    
  • Compile with the -ffriend-injection flag, which eliminates the error.

These solutions seem to be inconsistent with the general rules of declaration/definition in C++ I know.

Why do I have to declare baz() twice?
Why is the definition otherwise only legal inside a namespace, and illegal with the scope resolution operator?
Why does the flag eliminate the error?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Why do I have to declare baz() twice?

Because the friend declaration doesn't provide a usable declaration of the function in the namespace. It declares that, if that function is declared in that namespace, it will be a friend; and if you were to define a friend function inside a class, then it would be available via argument-dependent lookup (but not otherwise) as if it were declared in the namespace.

Why is the definition otherwise only legal inside a namespace, and illegal with the scope resolution operator?

Because it hasn't been (properly) declared in the namespace, and a function can only be defined outside its namespace (with scope resolution) if it has been declared.

Why does the flag eliminate the error?

Because the flag causes the friend declaration to act as a declaration in the namespace. This is for compatibility with ancient dialects of C++ (and, apparently, some modern compilers) in which this was the standard behaviour.


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

...