对 std::array 的模板化引用未在 MSVC 中调用 SFINAE*。漏洞?

Templated references to std::array not invoking SFINAE* in MSVC . Bug?

我 运行 遇到一个问题,将模板化数组引用升级到 std::array 我曾经使用过这个:

template<class T, int N>
void f(T(&a)[N]){/* do stuff */;}

这在我使用过的所有编译器中都有效,所以我只是在更改为 std::array

时才这样做
template<class T, int N>
void f(std::array<T,N>& a){/* do stuff */;}

这在 MSVC 上运行良好。但是当我 运行 其他编译器上的代码时它没有 以下代码在 MSVC 中有效,但在其他编译器中无效。请参阅无法匹配的 https://godbolt.org/z/d9cqWMeaM,因为 N 必须是 std::size_t

*这个question表示应该申请SFINAE。但是,正如评论中所指出的那样,尽管有这个答案,SFINAE 通常适用于拒绝格式错误的声明。这是推演失败

MSVC 接受这段代码是编译器错误吗?即使我用过的所有编译器都没有问题,T(&a)[N] 使用 int N 是否合法?

这有点烦人,因为之前的一些代码使用了 N 在不同地方签名的事实。

std::array size_typespecified 作为 std::size_t.

GCC 和 Clang 是对的,根据 [temp.deduct.type]/18:

,在这种情况下模板推导应该会失败

If P has a form that contains <i>, and if the type of i differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails.
. . .

[ Example:

template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
void k1() {
  A<1> a;
  f(a);             // error: deduction fails for conversion from int to short
  f<1>(a);          // OK
}

注意:在 C++11 中,此规则更易于阅读,请参阅 here

所以从技术上讲,MSVC 对代码的接受是一个错误。我会向供应商报告(帮助 -> 发送反馈 -> 报告问题)。