由于成员函数与参数类型的名称冲突,模板构造函数在 MSVC 中失败

Template constructor fails in MSVC due to name collision of member function with argument type

以下代码片段在 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

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

2) A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

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