[英]clang vs gcc template child class using forward-declared class in parent
I have a template child class (the template typename is not related to parent or child, so not a CRTP inheritance case), and the parent has a forward-declared class in the private access label section. 我有一个模板子类(模板typename与父或子不相关,因此不是CRTP继承的情况),并且父类在私有访问标签部分中有一个前向声明的类。
GCC (tested on 4.9.2 and 7.2) compiles, but clang (tested on 5.0.0) will complain. GCC(在4.9.2和7.2上测试)编译,但clang(在5.0.0上测试)会抱怨。 This is the repro case:
这是repro案件:
class TestClass
{
public:
// Forward-declare as public to make compile with clang
// class Thing;
private:
// GCC compiles fine with forward-declaration as private but clang gives error
class Thing;
friend class Thing;
void NotifyOfThing();
};
class TestClass::Thing
{
public:
static void NotifyOfThing() {}
};
template <typename Unrelated>
class ThingImpl final : public Unrelated
{
private:
void handleThing()
{
TestClass::Thing::NotifyOfThing();
}
};
int main() {
ThingImpl<TestClass> implementation;
}
Clang throws an error: Clang抛出一个错误:
25 : <source>:25:20: error: 'Thing' is a private member of 'TestClass'
TestClass::Thing::NotifyOfThing();
^
8 : <source>:8:11: note: declared private here
class Thing;
^
1 error generated.
Compiler exited with result code 1
GCC however accepts this. 然而GCC接受了这一点。
Now if I remove the template declaration, and make ThingImpl
a non-template class, GCC will also have the same complaint about Thing
being private. 现在,如果我删除模板声明,并使
ThingImpl
成为非模板类,GCC也会抱怨Thing
是私有的。
Can someone explain why this is the case, and which one complies more with the C++ standard? 有人可以解释为什么会出现这种情况,哪一个更符合C ++标准? Or does the standard not cover this explicitly?
或者标准没有明确涵盖这一点?
gcc has many bugs when it comes to access checking in templates. 当访问模板中的检查时,gcc有很多错误。 See this meta-bug .
看到这个meta-bug 。 The situation you have matches 41437 exactly:
你遇到的情况恰好与41437相符:
class A { struct B { B(); }; };
template<typename T> void f() { A::B b; }
void g() { f<int>(); } // gcc says this is okay
clang is correct, the code is clearly ill-formed. 铿锵是正确的,代码显然是不正确的。
Thing
is a private class of TestCalss
, and ThingImpl
is not a friend of TestClass
, so ThingImpl
trying to access TestClass::Thing
should be an access violation. Thing
是TestCalss
的私有类,而ThingImpl
不是TestClass
的朋友,因此ThingImpl
尝试访问TestClass::Thing
应该是访问冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.