12

有谁知道为什么 using-declarations 似乎不适用于从依赖基类导入类型名称?它们适用于成员变量和函数,但至少在 GCC 4.3 中,它们似乎被类型忽略了。

template <class T>
struct Base
{
  typedef T value_type;
};

template <class T>
struct Derived : Base<T>
{
  // Version 1: error on conforming compilers
  value_type get();

  // Version 2: OK, but unwieldy for repeated references
  typename Base<T>::value_type get();

  // Version 3: OK, but unwieldy for many types or deep inheritance
  typedef typename Base<T>::value_type value_type;
  value_type get();

  // Version 4: why doesn't this work?
  using typename Base<T>::value_type;
  value_type get(); // GCC: `value_type' is not a type
};

我有一个带有一组分配器样式 typedef 的基类,我想在多个继承级别中继承它们。到目前为止我发现的最佳解决方案是上面的第 3 版,但我很好奇为什么第 4 版似乎不起作用。GCC 接受 using 声明,但似乎忽略了它。

我检查了 C++ 标准,C++ Prog。朗。第三版。[Stroustrup] 和 C++ 模板 [Vandevoorde, Josuttis],但似乎都没有解决 using-declarations 是否可以应用于依赖的基类类型。

如果查看另一个示例会有所帮助,请在 GCC 邮件列表上提出相同的问题,但没有真正回答。提问者表示他在其他地方看到过“使用 typename”,但 GCC 似乎不支持它。我没有其他符合标准的编译器可用于测试它。

4

2 回答 2

10

正如 Richard Corden 所指出的,在 2003 年标准被批准后,这个问题在C++ 标准核心语言缺陷报告中得到了解决:关键字 typename/template 如何与 using-declarations 交互?

提议的决议(2003 年 4 月,2003 年 10 月修订):

在 7.3.3 [namespace.udecl] 的底部添加一个新段落:

如果 using-declaration 使用关键字 typename 并指定依赖名称 (14.7.2 [temp.dep]),则 using-declaration 引入的名称被视为 typedef-name (7.1.3 [dcl.typedef]) .

从 2003 年 10 月 15 日起,该文本似乎未出现在第二版标准中。

GCC 尚未实现此解决方案,如错误 14258中所述:

------- 评论 #3 来自 Giovanni Bajo 2004-02-27 12:47 [回复] ------- 问题是我们的 USING_DECL 没有记录“类型名”,这是事实它是通过它导入的类型。我相信,这要归功于隐式类型名称扩展。

重复的错误 21484表明“使用 typename”适用于 Comeau 和 Intel 编译器。因为 MSVC 将所有名称视为依赖,所以该构造对于该编译器来说是不必要的(但允许)。


2011 年 12 月 13 日在 GCC 4.7 中修复!

于 2009-07-01T21:22:52.413 回答
-2

在为 Base::value_type 声明 typedef 之前,您没有在 Base 的模板中包含访问说明符(public/protected/private)。因此,它默认为私有,并且在从 Base 派生的类中不可访问。

于 2009-07-01T20:19:35.677 回答