【问题标题】:A 'using' statement compiles with g++, fails compilation with clang'using' 语句使用 g++ 编译,使用 clang 编译失败
【发布时间】:2015-03-13 08:16:42
【问题描述】:

我有以下结构的代码(在现实中当然要复杂得多,尤其是“Base”是一个三行代码,但我试图抓住它的要点):

template <class T>
class A {};

template <class T>
class B {
public:
    B(){};
};

template <class T>
class C : public B<A<T>> {
public:
    using Base = B<A<T>>;
    using Base::B;
};

static const C<int> c{};

代码通过 g++ 编译良好​​p>

g++ -c test.cpp -std=c++11

但是,使用 clang++ 时,我收到一条我不太明白的错误消息

clang++ -c test.cpp -std=c++11

test.cpp:14:14:错误:依赖使用声明解析为没有“类型名称”的类型 使用 Base::B;

我的代码有什么问题吗?或者这是 clang 中的错误?

注意:在编写 using B&lt;A&lt;T&gt;&gt;::B; 时,两个编译器都可以正常编译,但这并不是我的问题的真正解决方案。

编辑:clang 版本是 3.5.0,gcc 版本是 4.9.2

【问题讨论】:

  • 使用继承构造函数时,using 命名构造函数,而不是类型,所以typename 是错误的。无论如何,using Base::Base 应该可以工作 - 名称查找中有一个特殊规则将其解析为构造函数。 coliru.stacked-crooked.com/a/5e01aeb4d26b312e
  • 感谢您的解释。 using Base::Base 是我生产代码的一个很好的解决方案。但是,问题仍然是using Base::B 是否有效。对我来说,错误提及typename 表明clang 有问题。但是,我不是 C++ 专家。
  • 是的,这看起来像一个 clang 错误。没有理由对 using B&lt;A&lt;T&gt;&gt;::B;using Base::B; 区别对待。
  • 谢谢,我已经提交了错误报告,并将相应地更新这个问题:llvm.org/bugs/show_bug.cgi?id=22242
  • @user2188211:所以回答你自己的问题并接受,然后:-)

标签: c++ compilation g++ clang


【解决方案1】:

这个案例已经在 C++ 委员会讨论过(根据 Richard Smith https://llvm.org/bugs/show_bug.cgi?id=23107#c1),现在事情变得更清楚了:

using Base::B

不是是有效代码。

以下方法是在引入类别名Base时表达构造函数继承的正确方式:

using Base::Base

但是,clang 生成的错误消息具有误导性,并有望作为此错误报告 (https://llvm.org/bugs/show_bug.cgi?id=22242) 的一部分得到解决。

【讨论】:

【解决方案2】:

从第 12.1 节开始:

构造函数没有名字

因此,合格查找的通常规则不适用。相反,您必须依赖构造函数查找的特殊规则(第 3.4.3.1 节):

在不忽略函数名称且 nested-name-specifier 指定类 C 的查找中:

——如果在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 Cinjected-class-name,或

using-declaration (7.3.3) 中,它是一个 member-declaration,如果在 nested-name 之后指定了名称-specifieridentifiersimple-template-id 的最后一个组件中的 template-name 相同嵌套名称说明符,

该名称被认为是命名类C的构造函数。

所以你当然可以写

using Base::Base;

而不是

using Base::B;

您的原始版本应该在第一个要点下工作,但是当涉及模板时,注入的类名会变得复杂。只需使用更简单的版本Base::Base,它也更具可读性。任何看到它的人都会立即知道您正在命名构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多