我有这段代码,用 g++ 13.3.0 成功编译。
template<typename T1>
class H1
{
template<typename T2>
class H2 {
void Hh(int) {}
};
};
// template<typename T3> // not compiling
class H3
{
template<typename T1>
template<typename T2>
friend void H1<T1>::H2<T2>::Hh(int); // The issue row 253
};
如果取消注释“template
g++ -std=c++17 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test1.d" -MT"src/Test1.o" -o "src/Test1.o" "../src/Test1.cpp"
../src/Test1.cpp:253:27: error: expected initializer before ‘<’ token
253 | friend void H1<T1>::H2<T2>::Hh(int);
| ^
朋友的定义应该改变什么?
虽然您可以将模板或依赖类型的成员声明为友元 ([temp.friend]/4–5),但这不会扩展到 template-declaration 中任意复杂的友元声明。 请注意,
H1<T1>::H2<T2>::Hh(int)
本身并不是函数模板。
GCC 显然在模板中检查得更加仔细,可能是因为它必须将友元声明的表示存储更长时间。