I wasted countless hours to pinpoint an issue with gcc. I wanted to test our code base with another compiler to look for more warnings that Clang might have missed. I was shocked that practically half of the project stopped to compile due to failure of template argument deduction. Here I've tried to dumb my case down to the simplest piece of code.
#include <type_traits>
struct Foo
{ };
// This is a template function declaration, where second template argument declared without a default
template <typename T, typename>
void foo(const Foo & foo, T t);
// This is a template function definition; second template argument now has a default declared
template <typename T, typename = typename std::enable_if<1>::type>
void foo(const Foo & foo, T t)
{
}
int main(int argc, char ** argv)
{
foo(Foo{}, 1);
return 0;
}
Ignore a 1
in the std::enable_if<1>
. Obviously it's a constant value just to not complicate things when it does not matter.
This piece of code compiles[1] with clang (3.4 through 4.0), icc (16, 17), Visual C++ (19.00.23506). Basically, I couldn't find any other c++11 compiler that, except gcc (4.8 through 7.1), does not compile this piece of code.
The question is, who's right and who's wrong here? Does gcc behave according to the standard?
Obviously this is not a critical issue. I can easily move std::enable_if
to the declaration. The only victim would be aesthetics. But it is nice to be able to hide an ugly 100 characters long std::enable_if
piece of code, that is not immediately relevant for the user of the library function, in the implementation.
Live example on godbolt.org.
question from:
https://stackoverflow.com/questions/43993162/all-versions-of-gcc-struggle-with-a-template-that-has-the-default-type-in-a-defi 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…