【问题标题】:C++ Compiler error with CRTPCRTP 的 C++ 编译器错误
【发布时间】:2011-01-11 23:41:33
【问题描述】:

我有以下类层次结构:

template <typename T>
class base
{
public:
   void f() {}
};

class class_a : public base<class_a> {};

class class_b : public base<class_b>, 
                public class_a 
{ 
   using base<class_b>::f; 
};

int main()
{
   class_b b;
   b.f();
   return 0;
}

Comeu 和 Intel C++ v11 声称一切正常,但 GCC (4.4.1) 和 VC++ 2008 似乎抱怨 (http://codepad.org/KQPDsqSp),例如:

g++ -pedantic -Wall -o test test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:5: error: ‘void base<T>::f() [with T = class_b]’ is inaccessible
test.cpp:14: error: within this context 

我相信代码的格式是正确的,但是我可能是错的,我希望 SO C++ 社区的人可以提供一些关于这个问题的见解。

注意: 在 class_b 的 using 指令前添加“public”,解决了 gcc 和 VS 的问题。应用 using 指令的类的访问器部分是否应该覆盖基类的派生模式(公共、私有)?

总之就是这样

  • 编译器错误 - 如果是编译器 GCC、VS 或 Comeu、Intel
  • 上面的代码格式正确吗?
  • 调用 using 指令的访问器部分是否会覆盖基类的派生模式?

【问题讨论】:

    标签: c++ templates compiler-errors crtp


    【解决方案1】:

    您在这里所做的是通过将符号导入类 private 命名空间来解决歧义。因此,它是方法阴影并将其可见性更改为私有。您不能拥有两个具有完全相同原型的函数,既私有又公有,因此 f 现在是私有的。

    至少 GCC 相信 using should be able to change the visibility 的一个函数。

    但在GCC bug database 中发现的模糊引用表明,使用实际上不应受到范围的影响。

    最重要的是,直接回答(C++ Standard '03 -- 7.3.3/15)

    使用声明创建的别名具有成员声明的通常可访问性。

    因此答案是:

    • 这是 Comeau 中的一个错误
    • 不,代码格式不正确,至少在 C++03 方面(在 C++0x N3000 中找不到任何相关内容)
    • 是的,您可以更改访问范围

    【讨论】:

    • 私有命名空间或范围内没有任何内容。并且 using 指令不考虑调用它的类的访问器部分 - 但是在 using 指令之前添加 public 确实可以解决问题。我相信在这种情况下 gcc 和 VS 有问题,你不觉得吗?
    • @darid,在上面提供的链接中,您会看到至少在 GCC 的情况下,它已明确更改为现在的方式。
    • @Kornel:这是一个很好的答案,我想补充一下,我已经使用 intel c++ 编译器尝试过它,它像 Comeau 一样喜欢它。我想知道它是否是解析器接口问题,intel 和 Comeau 是从 EDG 获得的,但 MS for VSC++ 也是如此,这只会让事情变得更加混乱。
    • @darid,好的,在 7.3.3/15 中找到了直接引用 :)
    • @Kornel:非常感谢! - 顺便说一句,谁会想到 Comeau 可能有错误! :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多