【问题标题】:Template constructor fails in MSVC due to name collision of member function with argument type由于成员函数与参数类型的名称冲突,模板构造函数在 MSVC 中失败
【发布时间】:2015-04-25 01:56:18
【问题描述】:

以下代码片段无法在 MSVC 18.00.31101 中编译并出现以下错误,但在 gcc 4.9.2 和 clang 3.6.0 中编译成功。限定参数类型或在声明中包含 struct 关键字可解决错误。这是编译器错误还是未定义的行为?

#include <cstdlib>

struct A {
    int B;
};

struct Snap {
    template<size_t TSize>
    Snap(const A (&)[TSize]) {
        // do something with TSize
    }

    void A() {}
};

int main() {
    A pop[] = { {1}, {2}, {3} };

    Snap crackle(pop);

    return 0;
}

.

1> <...>: error C2664: 'Snap::Snap(const Snap &)' : cannot convert argument 1 from 'A [3]' to 'const Snap &'
1>          Reason: cannot convert from 'A [3]' to 'const Snap'
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

【问题讨论】:

  • 您可以将 clang 3.6.0 添加到可以工作的编译器列表中。 See it live
  • 只是好奇,如果你写出Snap(const struct A (&amp;)[TSize]),那么MSVC会编译它吗?
  • 是的,这也解决了。

标签: c++ templates visual-c++


【解决方案1】:

这是格式错误的,但不需要诊断。 [basic.scope.class]/p1:

2) 在类S 中使用的名称N 应引用相同的声明 它的上下文以及在S 的完整范围内重新评估时。不 违反此规则需要进行诊断。

在其上下文中评估的名称A 指的是::A,但在Snap 的完整范围内重新评估时指的是Snap::A

【讨论】:

  • 使用struct 限定类型声明是否使程序格式正确,或者这是否仅有助于编译器执行预期的名称解析,尽管仍然格式错误?
  • @qartar 该查找忽略了非类型名称,所以我认为它应该在两种上下文中都找到::A,使其格式正确。
猜你喜欢
  • 2011-04-15
  • 2012-10-01
  • 1970-01-01
  • 2019-11-23
  • 2015-02-26
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
  • 2017-11-03
相关资源
最近更新 更多