对 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_type
是 specified 作为 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 对代码的接受是一个错误。我会向供应商报告(帮助 -> 发送反馈 -> 报告问题)。
我 运行 遇到一个问题,将模板化数组引用升级到 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_type
是 specified 作为 std::size_t
.
GCC 和 Clang 是对的,根据 [temp.deduct.type]/18:
,在这种情况下模板推导应该会失败If
P
has a form that contains<i>
, and if the type ofi
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 对代码的接受是一个错误。我会向供应商报告(帮助 -> 发送反馈 -> 报告问题)。