I am writing some TMP-heavy code for g++ (version 4.8.1_1, Macports) and clang++ (version 3.3, Macports). While g++ rejects the following code listing with UNBRIDLED FURY, clang++ compiles it with grace and splendor.
- Which complier is in the right? (I strongly suspect it's g++, but I want to get some reassurance from others before submitting a bug report.)
- Do you have any easy or elegant workarounds to suggest? (I need to use template aliases, so switching over to structs, which causes g++ to accept the code, is not an option.)
Here is the code listing, made just for you.
template <class... Ts>
struct sequence;
template <int T>
struct integer;
// This definition of `extents` causes g++ to issue a compile-time error.
template <int... Ts>
using extents = sequence<integer<Ts>...>;
// However, this definition works without any problems.
// template <int... Ts>
// struct extents;
template <int A, int B, class Current>
struct foo;
template <int A, int B, int... Ts>
struct foo<A, B, extents<Ts...>>
{
using type = int;
};
template <int B, int... Ts>
struct foo<B, B, extents<Ts...>>
{
using type = int;
};
int main()
{
using t = foo<1, 1, extents<>>::type;
return 0;
}
Here is g++'s output:
er.cpp: In function 'int main()':
er.cpp:39:41: error: ambiguous class template instantiation for 'struct foo<1, 1, sequence<> >'
using t = typename foo<1, 1, extents<>>::type;
^
er.cpp:26:8: error: candidates are: struct foo<A, B, sequence<integer<Ts>...> >
struct foo<A, B, extents<Ts...>>
^
er.cpp:32:8: error: struct foo<B, B, sequence<integer<Ts>...> >
struct foo<B, B, extents<Ts...>>
^
er.cpp:39:43: error: 'type' in 'struct foo<1, 1, sequence<> >' does not name a type
using t = typename foo<1, 1, extents<>>::type;
^
Here is clang++'s output:
Thanks for your help!
+1
for jokes alone :) I'd also bet that Clang is right here. – Boadiceatypename
inmain
is unneeded – FrenchifyI need to use template aliases
Mankind survived without them for the last several million years... I'm sure another five won't kill you. – Doublecross