如何在Clang中声明模板类的构造函数为友元?(G++可编译,Clang++不可)
解决模板类私有构造函数的跨实例友元声明问题
你的问题出在友元声明的语法不符合C++标准,Clang比GCC更严格遵循标准,因此触发报错。你原本想让foo模板的所有实例都能访问彼此的私有构造函数,但直接声明另一个实例的构造函数为友元的写法存在语法问题:
- Clang认为
foo<U>::foo是依赖类型名,要求添加typename,但构造函数并非类型,加了typename后会被当成类型,进而触发「友元只能是类或函数」的错误;而GCC做了非标准的宽松解析,所以能编译通过,但这种写法本身不符合标准规范。
最优解决方案:声明整个模板类为友元
最简单且符合标准的写法是直接把整个foo模板类声明为友元,这样所有foo<U>实例的所有成员都能互相访问私有成员,完全满足你的需求:
template <typename T> class foo { foo(T){} template <typename U> friend class foo; // 声明整个模板类为友元 public: foo(){} }; int main() { foo<int> a{}; }
可选方案:单独声明构造函数为友元(不推荐)
如果一定要单独声明构造函数为友元(没必要,不如前者简洁),可以用以下写法,但部分编译器仍可能存在兼容性问题:
template <typename T> class foo; // 前置声明模板类 template <typename T> class foo { foo(T){} template <typename U> friend foo<U>::foo(U); public: foo(){} }; // 显式定义构造函数 template <typename T> foo<T>::foo(T) {} int main() { foo<int> a{}; }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

