Consider the following code:
template <class T, class U, class V> struct Foo { }; template <class T, class U> struct Foo<T, U, std::integral_constant<int, U::value>> { static void print() { std::cerr << "instantiated"; } }; template <class U> struct Foo<double, U, std::integral_constant<int, U::value>> { static void print() { std::cerr << "instantiated special"; } }; struct Bar { static const int value = 0; }; int main(int argc, char ** argv) { using Baz = Foo<double, Bar, std::integral_constant<int, 0>>; Baz::print(); return 0; }
When I compile this with icc 16.0.1, I get the following message:
main.cpp(38): error: more than one partial specialization matches the template argument list of class "Foo<double, Bar, std::integral_constant<int, 0>>" "Foo<T, U, std::integral_constant<int, U::value>>" "Foo<double, U, std::integral_constant<int, U::value>>" Baz::print();
With clang 3.7.1 and gcc 5.3.0, this compiler (and the "instance of the special instance" is printed). Is it an icc error or the wrong code? It seems to me that the second specialization is strictly specialized than the first; it is identical to the first, except that it blocks the first parameter of the template.
Edit: I have to add: if this is a bug in icc, is there a good workaround?