CRTP的C++编译器错误

6 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;
}
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

我相信代码很好,但是我可能错了,我希望来自SO C++社区的人能够对这个问题提供一些见解.

注意:在class_b中的using指令之前添加"public"可以解决gcc和VS的问题.应用using指令的类的访问器部分是否应该覆盖基类的派生模式(public,private)?

简而言之就是这样

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

Kor*_*icz 3

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

至少GCC认为using应该能够改变函数的可见性。

然而,在GCC bug 数据库中发现的模糊引用表明,使用实际上不应受到范围的影响。

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

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

因此答案是:

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

  • @Kornel:非常感谢!- 顺便说一句,谁会想到科莫可能有一个错误!:D (3认同)
  • @darid,在上面提供的链接中,您会看到至少在 GCC 的情况下,它已明确更改为现在的方式。 (2认同)
  • @darid,好的,在 7.3.3/15 中找到了直接引用:) (2认同)