#include <cstddef>
template<typename T, T... Is>
struct Bar { };
template<size_t... Is>
using Baz = Bar<size_t, Is...>;
struct Foo {
template<size_t... Is>
void NoAlias(Bar<size_t, Is...>) { }
template<size_t... Is>
void Alias(Baz<Is...>) { }
};
template<typename T, T... Is>
void foo(Bar<T, Is...>) { }
template<size_t... Is>
void bar(Bar<size_t, Is...>) { }
int main() {
// All these work fine
foo(Bar<size_t, 4, 2>());
foo(Baz<4, 2>());
bar(Bar<size_t, 4, 2>());
bar(Baz<4, 2>());
Foo().NoAlias(Bar<size_t, 4, 2>());
Foo().NoAlias(Baz<4, 2>());
// But these two give error on ICPC (ICC) 14.0.2:
// no instance of function template "Foo::Alias" matches the argument list
// Note the only difference between NoAlias and Alias is (not) using the alias
// for the member function parameter
Foo().Alias(Bar<size_t, 4, 2>());
Foo().Alias(Baz<4, 2>());
return 0;
}
ICC 14.0.2 gives error:
$ icc -std=c++11 -Wall -pedantic -pthread -o .scratch{-,.}cpp && ./.scratch-cpp
.scratch.cpp(36): error: no instance of function template "Foo::Alias" matches the argument list
argument types are: (Bar<size_t, 4UL, 2UL>)
object type is: Foo
Foo().Alias(Bar<size_t, 4, 2>());
^
.scratch.cpp(37): error: no instance of function template "Foo::Alias" matches the argument list
argument types are: (Baz<4UL, 2UL>)
object type is: Foo
Foo().Alias(Baz<4, 2>());
^
However, it compiles with both GCC 4.8 and Clang 3.4.2. (Tested on a 64-bit Linux.)
Can anybody who is well acquainted with the C++11 standard confirm this is indeed a bug?
Also, is there an easy preprocessor-based workaround?
Your example is (clearly) well-formed. §14.8.2.5/9 describes how deduction is performed in this case.
If
P
has a form that contains<T>
or<i>
, then each argumentP
i of the respective template argument listP
is compared with the corresponding argumentA
i of the corresponding template argument list ofA
. […]. IfP
i is a pack expansion, then the pattern ofP
i is compared with each remaining argument in the template argument list ofA
. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded byP
i.
Moreover, your code is compiling with version 15.0.3 on my machine. Hence upgrading the compiler should fix the issue. I can't see another simple workaround.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With