首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clang对gcc模板子类使用父类中的前向声明类

clang对gcc模板子类使用父类中的前向声明类
EN

Stack Overflow用户
提问于 2017-10-16 02:07:21
回答 1查看 245关注 0票数 3

我有一个模板子类(模板类型名称与父类或子类无关,因此不是CRTP继承情况),并且父类在私有访问标签部分中有一个前向声明的类。

GCC (测试4.9.2和7.2)编译,但clang (测试5.0.0)会抱怨。这就是复制案例:

代码语言:javascript
复制
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抛出一个错误:

代码语言:javascript
复制
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接受了这一点。

现在,如果我删除模板声明,并使ThingImpl成为一个非模板类,GCC也会有同样的抱怨,Thing是私有的。

有人能解释为什么会出现这种情况,哪一个更符合C++标准?还是标准没有明确地涵盖这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-16 03:12:01

gcc在访问签入模板方面有很多错误。见这个元错误。与41437完全匹配的情况如下:

代码语言:javascript
复制
class A { struct B { B(); }; };
template<typename T> void f() { A::B b; }
void g() { f<int>(); } // gcc says this is okay

clang是正确的,代码显然是不正确的.ThingTestCalss的一个私有类,ThingImpl不是TestClass的朋友,所以ThingImpl试图访问TestClass::Thing应该是一种访问冲突。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46762007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档