【发布时间】:2014-04-19 14:35:33
【问题描述】:
我有一个模板类,我在类中定义了一个友元函数。
#include <iostream>
using namespace std;
template <typename T>
class template_class {
T v;
friend void foo(template_class t) {
t.v = 1; // (1)can access the private member because it's a friend
cout << t.v << endl;
template_class<int> t1;
t1.v = 2; // (2)accessible if instantiated with [T=int]
cout << t1.v << endl;
template_class<char> t2;
t2.v = 'c'; // (3)should not be accessible too if instantiated with [T=int]
cout << t2.v << endl;
}
};
int main() {
template_class<int> t; // (4)generate void foo(template_class<int> t)
foo(t);
return 0;
}
如果我的理解是正确的,(4)生成函数void foo(template_class<int>),并使其成为template_class<int>的朋友,这样它就可以访问template_class<int>的私有成员,就像上面的(1)和(2)一样资源。但是(3)也应该不行,不是template_class<char>的朋友,只有void foo(template_class<char>)会是template_class<char>的朋友。
编辑 正如@Constructor 和@Chnossos 所说,上述源代码使用gcc 4.8.1 编译正常,但使用clang 3.4 编译失败。那么哪一个是正确的呢?它只是gcc的一个错误吗?标准对这种情况有明确的定义吗?
【问题讨论】:
-
@πάνταῥεῖ “朋友关系不共享。”但是为什么函数可以同时访问
template_class<int>和template_class<char>的私有成员呢? -
你的代码不能用clang 3.4编译。
-
它可以很好地与gcc 4.8.1 一起编译。
-
IIRC 这是一个 g++ 错误,可能与 gcc.gnu.org/bugzilla/show_bug.cgi?id=41437 相关?
-
@songyuanyao g++ 中的类/函数模板中有几个与访问控制问题相关的错误。其中一些可能在较新版本的 g++ 中得到修复,但我认为很明显,您的情况下的行为违反了 C++ 标准:为
template_class的每个实例化声明了一个函数foo,并且这些函数中的每一个都是仅是已在其中声明的实例化的朋友。
标签: c++ templates gcc access-control friend-function