Case 1
The following code produces drastically different results in MSVC and GCC:
#include <iostream>
template <typename T>
void foo(const T&) {
#ifdef _MSC_VER
std::cout << "foo(const T&): " << __FUNCDNAME__ << std::endl;
#else
std::cout << __PRETTY_FUNCTION__ << std::endl;
#endif
}
void foo(const char*) {
std::cout << "foo(const char*)" << std::endl;
}
int main() {
extern char s[];
foo(s);
}
char s[] = "abc";
MSVC 2013 Update 5, MSVC 2015 Update 1 (also tried Update 2 on http://webcompiler.cloudapp.net with the same result):
foo(const char*)
GCC 5.3.0, Clang 3.7.0 (DEMO):
void foo(const T&) [with T = char []]
Case 2
Now let's remove the templates:
#include <iostream>
void foo(const char(&)[]) {
std::cout << "foo(const char(&)[])" << std::endl;
}
void foo(const char*) {
std::cout << "foo(const char*)" << std::endl;
}
int main() {
extern char s[];
foo(s);
}
char s[] = "abc";
MSVC produces error:
error C2668: 'foo' : ambiguous call to overloaded function
could be 'void foo(const char *)'
or 'void foo(const char (&)[])'
GCC produces another error (with both -std=c++14
and -std=c++1z
):
main.cpp:3:29: error: parameter '<anonymous>' includes reference to array of unknown bound 'const char []'
void foo(const char(&)[]) {
And Clang compiles with both -std=c++14
and -std=c++1z
and outputs:
foo(const char(&)[])
For the first case, in my opininon with C++14 the specialization void foo(const T&) [with T = char []]
shouldn't have been produced in the first place, so MSVC is right. But in C++1z GCC and Clang are right.
For the second case, I think with C++14 GCC is right and with C++1z Clang is right.
(The important difference between C++14 and C++1z here is CWG 393)
So the questions are, which compiler is right in the first and the second cases in C++14 (N4140) and C++1z (N4567)?
And another question, which compiler(s), if any, should I file a bug for?