【问题标题】:Trying to resolve a gcc specific compilation error试图解决 gcc 特定的编译错误
【发布时间】:2020-02-20 00:03:19
【问题描述】:

这是我正在尝试编译的程序。

template <typename T>
struct A
{
    T foo() const
    {
        return 1;
    }
};

template <typename T>
struct B : A<T>
{
    using U = A<T>;
    T foo() const
    {
        return 2;
    }
};

template <typename T>
struct D
{
    B<T> b;
    int foo() const
    {
        // using U = typename B<T>::U; // compilation succeeds if I uncomment this line
        return b.U::foo();
    }
};

int main()
{
    D<int> d;
    return d.foo();
}

我在 gcc 9.2、clang 9.0.0 和 icc19.0.1 中看到了不同的行为。 该程序无法使用 gcc 进行编译,并给出错误 U has not been declared,使用 clang 可以正常编译,并且使用 icc 进行了非常重要的程序集。 为什么这些编译器的行为不同?

我尝试阅读dependent_name,但由于无法正确阅读而放弃了。据我所知,结构D 中的数据成员b 具有依赖类型,而U 应该在模板实例化时被解析。

在 godbolt.org 上使用上述编译器编译上述代码:https://godbolt.org/z/n_Wl44。我使用带有 -O3 标志的 C++17。提前谢谢!!!

【问题讨论】:

  • 如果你把所有的编译器都带进来,看起来像 50/50:godbolt.org/z/F1JnWH
  • @TedLyngmo 哇,太棒了。我不知道一致性查看器。
  • 几天前我自己注意到了。非常好!但我怀疑这是一个小错误。颜色并不总是与结果匹配等。
  • 我认为这只是 GCC 中的一个错误。你应该举报。
  • Gcc 应该找到 U,因为它是 D 中的从属名称,并且由于限定成员名称查找规则:eel.is/c++draft/basic.lookup.classref#4

标签: c++


【解决方案1】:

b.U::foo(); 中的U 应该在实例化过程中首先在B&lt;T&gt; 的上下文中查找,找到using U = A&lt;T&gt;;,以便b.U::foo() 调用A&lt;T&gt; 中定义的foo()[basic.lookup.classref]/4

查找应该延迟到实例化,并且不应该在定义处查找,因为b 是依赖的,因为它的类型取决于模板参数T[temp.dep.expr]/5

因此,这似乎是 GCC 中的一个错误。 this bug report 中发布了一个非常相似的代码示例,据我所知,它演示了相同的问题。该错误当前标记为“新”状态。

据我所知,the godbolt.org conformance view posted by @TedLyngmo 中显示的其他失败编译器是 GCC 的衍生产品,因此独立编译器对此并不存在分歧。

【讨论】:

    猜你喜欢
    • 2013-02-21
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多