Warning defining a friend statement declared inside a namespace

Can anyone explain me a warning from g ++?

Given the following code

#include <iostream>

namespace foo
 {
   struct bar
    { friend std::ostream & operator<< (std::ostream &, bar const &); };
 }

std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
 { return o; }

int main ()
 {
   foo::bar  fb;

   std::cout << fb;
 }

I get (from g ++ (6.3.0), but not from clang ++ (3.8.1) and not (thanks Robert.M) from Visual Studio (community 2017)) this warning

tmp_002-11,14,gcc,clang.cpp:10:16: warning: ‘std::ostream& foo::operator<<(std::ostream&, const foo::bar&)’ has not been declared within foo
 std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
                ^~~
tmp_002-11,14,gcc,clang.cpp:7:29: note: only here as a friend
     { friend std::ostream & operator<< (std::ostream &, bar const &); };
                             ^~~~~~~~

I know that I can define an operator as follows

namespace foo
 {
   std::ostream & operator<< (std::ostream & o, bar const &)
    { return o; }
 }

but ... what happened to my source code?

+4
source share
3 answers

Consider this simpme program:

namespace xxx { 
    struct foo {
       friend void bar();
    };
}

int main() {
    xxx::bar();
}

You will get a compilation error (with clang too) because it is barnot declared in the namespace xxx.

Now consider the following:

namespace xxx {}
void xxx::bar() {}

, bar xxx.

, , , . bar xxx. , . .

+3

n.m. , , , , , :

CppCoreGuidelines , ", , , " . .
, GCC : , GCC im 2016.

. , < < foo , :

namespace foo
{
    struct bar
    { 
        friend std::ostream & operator<< (std::ostream &, bar const &);
    };

    // Implementation
    std::ostream & operator<< (std::ostream & o, foo::bar const &)
    { return o; }
}

, , , .

, SO- . , (gcc 7 , ).

+2

, , , , , - .

        const type_name variable_id &;

, const - , .

:

        friend std::ostream & operator<< (std::ostream &,const bar&);

:

std::ostream & foo::operator<< (std::ostream & o,  const foo::bar &)
0

Source: https://habr.com/ru/post/1680079/


All Articles