-
21-08-2019 - |
题
有谁知道为什么 using 声明似乎不适用于从依赖基类导入类型名称?它们适用于成员变量和函数,但至少在 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 声明是否可以应用于依赖基类类型。
如果看另一个例子有帮助的话, 这是同样的问题, ,但在 GCC 邮件列表上没有真正得到答复。提问者表示他在其他地方看到过“使用类型名”,但 GCC 似乎不支持它。我没有其他符合标准的编译器可用于测试它。
解决方案
正如理查德·科登 (Richard Corden) 指出的那样,这个问题已在 C++ 标准核心语言缺陷报告 2003年标准批准后: 关键字 typename/template 如何与 using 声明交互?
拟议决议(2003年4月,2003年10月修订):
在7.3.3的底部添加一个新段落[namespace.udecl]:
如果使用declaration使用关键字键入并指定依赖性名称(14.7.2 [temp.dep]),则使用使用declaration引入的名称被视为typedef-name(7.1.3 [dcl.typedef]) 。
这段文字似乎没有出现在 2003 年 10 月 15 日的第二版标准中。
GCC 尚未实施该决议,如 错误 14258:
-------评论#3来自Giovanni Bajo 2004-02-27 12:47 [回复] -------问题是我们的使用_decl没有记录“ typeName”,这就是事实它是通过它导入的一种类型。我相信,由于隐式类型的扩展,这曾经起作用。
复制 错误 21484 表示“using typename”适用于 Comeau 和 Intel 编译器。由于 MSVC 将所有名称视为从属名称,因此该构造对于该编译器来说是不必要的(但允许)。
固定的 2011 年 12 月 13 日在 GCC 4.7 中发布!
其他提示
您没有宣布对基地:: value_type的typedef的前包括在模板中为基地访问符(公共/保护/私营)。其结果,则默认为私人和不从碱衍生的类访问。