Please consider the code:
#include <iostream>
using namespace std;
extern "C"
void foo( void );
namespace A
{
template< int No >
class Bar
{
private:
friend void ::foo( void );
static void private_func( int n );
};
template< int No >
void Bar< No >::private_func( int n )
{
cout << "A:Bar< " << No << ">::private_func( " << n << " )" << endl;
}
}
extern "C"
void foo( void )
{
A::Bar< 0 >::private_func( 1 );
}
int main( )
{
cout << " ---- " << endl;
foo( );
}
G++ gives:
> g++ -Wall -o extern_c extern_c.cpp
extern_c.cpp: In function ‘void foo()’:
extern_c.cpp:20:7: error: ‘static void A::Bar<No>::private_func(int) [with int No = 0]’ is private
extern_c.cpp:29:31: error: within this context
If I comment the namspace A, it will compile and run correctly.
What am I missing?
I looked related topics, but could not find any that fits in my problem.
- C++: namespace conflict between extern "C" and class member
- Why this friend function can't access a private member of the class?
Thanks people.
EDIT:
I am now convinced that extern "C" has nothing to do with the problem.
Please ignore it.
I don't know the explanation, but if you put foo( ) into a namespace, it works.
#include <iostream>
using namespace std;
namespace C
{
extern "C"
void foo( void );
}
namespace A
{
template< int No >
class Bar
{
private:
friend void C::foo( void );
static void private_func( int n );
};
template< int No >
void Bar< No >::private_func( int n )
{
cout << "A::Bar< " << No << ">::private_func( " << n << " )" << endl;
}
}
namespace C
{
extern "C"
void foo( void )
{
A::Bar< 0 >::private_func( 1 );
}
}
int main( )
{
cout << " ---- " << endl;
C::foo( );
}
And the result:
bbcaponi@bbcaponi friends]$ g++ -Wall namespace_friend.cpp -o namespace_friend
[bbcaponi@bbcaponi friends]$ ./namespace_friend
----
A::Bar< 0>::private_func( 1 )
It's a g++ bug. Exists in 4.4, fixed in 4.6.
UPD: It seems that it's triggered by a combination of template and namespace. extern "C" is not relevant, as it may be commented out and the error remains.
You need to declare the friend as extern "C". Your current friend declaration finds a friend foo in the global namespace that has C++ name mangling.
来源:https://stackoverflow.com/questions/6821290/c-global-extern-c-friend-cant-reach-private-member-on-namespaced-class