template<typename Host>
class Foo
{
friend Host; // g++ 不能编译
};
楼主撞上敏感问题了,根据现行 C++03 标准,你的写法是明确禁止的,参见标准 7.1.5.3/2 (注意其中红色部分)
3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. If the identifier resolves to a typedef-name or a template type-parameter, the elaborated-type-specifier is ill-formed. [Note: this implies that, within a class template with a template type-parameter T, the declaration
friend class T;
is ill-formed. ] If name lookup does not find a declaration for the name, the elaborated-type-specifier is ill-formed unless it is of the simple form class-key identifier in which case the identifier is declared as described in 3.3.1.
有趣的是正在审议的新版标准 c++0x,对此有不同的解释,参见 n3126,7.1.6.3/2 (注意红色部分)
3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. If the identifier resolves to a typedef-name, the elaborated-type-specifier is ill-formed. [ Note: this implies that, within a class template with a template type-parameter T, the declaration
friend class T;
is ill-formed. However, the similar declaration friend T; is allowed (11.4). — end note ]
#include<iostream>
using namespace std;
template<typename T>
class identity {
public:
typedef T me;
};
template<typename my_friend>
class Foo {private:
friend class identity<my_friend>::me;
int i, j;
void show() {
cout << "Foo show" << endl;
}
;
};
class A {
Foo<A> fa;
public:
void seti(int i) {
fa.i = i;//A作为Foo<A>的友元访问其私有成员变量
}
;
};
class B {
public:
static void show(Foo<B> &fb) {
fb.show();//B作为Foo<B>的原有访问其私有函数
}
};
int main(int argc, char** argv) {
A a;
a.seti(0);
B b;
Foo<B> fb;
b.show(fb);
return 0;
}