CRTP的C ++编译器错误

时间:2010-02-02 01:27:48

标签: c++ templates compiler-errors crtp

我有以下类层次结构:

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和英特尔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指令的类的访问器部分是否应该覆盖基类的派生模式(public,private)?

简而言之就是这个

  • 编译器错误 - 如果是这样,编译器GCC,VS或Comeu,Intel
  • 上面的代码是否形成良好?
  • 调用using指令的访问器部分是否会覆盖基础的派生模式?

1 个答案:

答案 0 :(得分:3)

您在此处所做的是通过将符号导入类私有命名空间来解决歧义。因此,它的方法是阴影并改变它对私人的可见性。你不能拥有两个完全相同的私有和公共原型的函数,因此f现在是私有的。

至少GCC认为using should be able to change the visibility是一个功能。

GCC bug database中的模糊引用表明实际使用不应受范围的影响。

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

  

using-declaration创建的别名具有成员声明的通常可访问性。

因此答案是:

  • 这是Comeau的错误
  • 不,代码编写得不好,至少是C ++ 03(在C ++ 0x N3000中找不到任何相关内容)
  • 是的,您可以更改访问范围