Reputation: 4299
I ran across a problem upgrading templated array references to std::array
where I had used this:
template<class T, int N>
void f(T(&a)[N]){/* do stuff */;}
This has worked in all compilers I have used so I just did this when changing to std::array
template<class T, int N>
void f(std::array<T,N>& a){/* do stuff */;}
And this worked fine on MSVC. But when I ran the code on other compilers it did not
The following code works in MSVC but not other compilers. See https://godbolt.org/z/d9cqWMeaM which fails to match because N must be std::size_t
.
*This question indicates that SFINAE should apply. However, as noted in the comments and in spite of the that answer, SFINAE, typically applies to rejection of malformed declarations. This is a deduction failure.
Is MSVC's acceptance of this code a compiler bug? And is the T(&a)[N]
where int N
was used legal even though all compilers I've ever used had no problem at all?
This was somewhat annoying because some of the prior code used the fact N was signed in various places.
Upvotes: 2
Views: 83
Reputation: 85471
std::array
size_type
is specified as std::size_t
.
GCC and Clang are right, template deduction should fail in this case, according to [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 }
Note: in C++11 this rule was a little more human-readable, see here.
So technically MSVC's acceptance of the code is a bug. I would report it to the vendor (Help -> Send Feedback -> Report a Problem).
Upvotes: 2