Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I declare a friend function in a namespace that takes an inner class as a parameter?

Consider this code:

namespace foo {}

class A
{
   class B
   {
   };

   friend int foo::bar( B& );
};

namespace foo
{
   int bar( A::B& )
   {
   }
}

G++ 4.4.3 tells me:

friendfun-innerclass.cpp:21: error: 'int foo::bar(A::B&)' should have been declared inside 'foo'

But I can't declare:

namespace foo
{
   int bar( A::B& );
}

before the class A definition because A::B hasn't been declared. And I can't declare "class A::B" obviously, to declare class B I have to give the definition of class A, and as far as I know the "friend" declarations have to be inside the definition of class A.

What's strange to me is that if I take function "bar()" out of namespace foo everything works fine. It seems counterintuitive to me that having a function inside a namespace or not inside a namespace changes whether the compiler will accept a friend function declaration in the class.

Does anybody know of a way to proprerly structure all the declarations and such to get this to work?

like image 979
Jay Walker Avatar asked Oct 11 '11 15:10

Jay Walker


People also ask

Can we declare friend function inside class?

Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions. Like member inline functions, they behave as though they were defined immediately after all class members have been seen, but before the class scope is closed (at the end of the class declaration).

Where can we declare a friend function in the class?

A friend function in C++ is defined as a function that can access private, protected and public members of a class. The friend function is declared using the friend keyword inside the body of the class.

Can we declare friend function outside the class?

The friend function can be a member of another class or a function that is outside the scope of the class. A friend function can be declared in the private or public part of a class without changing its meaning.

How can we declare a class a friend of another class in C++?

Friend Keyword in C++ But, to declare any class as a friend class, you do it with the friend keyword. You can use the friend keyword to any class to declare it as a friend class. This keyword enables any class to access private and protected members of other classes and functions.


1 Answers

Can't be done the way you want to, because you would have to forward declare a nested class (which you can't) in order to provide a prototype for foo::bar.

As a first attempt to get around this problem, I would probably resort to making foo::bar a function template. That way the compiler will resolve the types after A and B are known.

Test harness:

namespace foo
{
    template<class B> int bar(B&);
};

class A
{
   class B
   {
       template<class B> friend int foo::bar( B& );
       int n_;
   public:
       B() : n_(42) {}
   };

public:
    B b_;
};

template<class B> int foo::bar(B& b)
{
    return b.n_;
}

int main()
{
    A a;
    foo::bar(a.b_);
}
like image 85
John Dibling Avatar answered Oct 13 '22 16:10

John Dibling