我有一个带有私有构造函数的模板类,它是该类的每个类型实例的朋友。以下在 g++ 11.4.0 下编译,但在 clang++ 版本 14.0.0-1ubuntu1.1 下失败
template <typename T>
class foo {
foo(T){}
template <typename U> friend foo<U>::foo(U);
public:
foo(){}
};
int main() {
foo<int> a{};
}
Run Code Online (Sandbox Code Playgroud)
clang 给出了错误
main.cpp:4:34: error: missing 'typename' prior to dependent type name 'foo<U>::foo'
template <typename U> friend foo<U>::foo(U);
^~~~~~~~~~~
typename
main.cpp:4:46: error: friends can only be classes or functions
template <typename U> friend foo<U>::foo(U);
Run Code Online (Sandbox Code Playgroud)
我不认为foo<U>::foo是依赖类型名称,但无论如何按照建议添加类型名称会导致错误
main.cpp:4:55: error: friends can only be classes or functions
template <typename U> friend typename foo<U>::foo(U);
Run Code Online (Sandbox Code Playgroud)
这似乎是 clang 中的编译器错误。如果我们看一下相关的情况,其中被友好的类模板构造函数属于不同的非模板类:
template<class T>
struct X {
X(T);
};
class C {
template<class U> friend X<U>::X(U);
C();
};
template<class T> X<T>::X(T) { C c; }
X<int> x(1);
Run Code Online (Sandbox Code Playgroud)
这为 clang 的行为提供了线索;它接受并带有警告:
警告:不支持友元类声明的依赖嵌套名称说明符“X::”;关闭“C”的访问控制 [-Wunsupported-friend]
因此,clang 缺少这方面的支持,并且在被友好的构造函数属于类模板的情况下没有意识到这一点(至少能够发出警告)。
最简单的解决方法可能是遵循https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42328#c4的建议并与全班同学交朋友:
template <typename U> friend class foo;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
120 次 |
| 最近记录: |