Over years of template metaprogramming practice, I have encountered all sorts of weird compiler bugs and errors. But with this one, I must say that I am somewhat puzzled. I have no idea which compiler is correct: ccc
, clang
, msvc
, and intel
all give different results (and as surprising as it may sound, only intel
compiles the code without errors). Even more surprising, it does not rely on any new C++
feature as only C++11
is involved.
The code will speak for itself as it is relatively simple. It only consists of a variadic template template wrapper with a variadic inner entity that can be either a struct or an alias template. And for whatever reason, the alias template version returns an error for some compilers when an instance of it is constructed:
#include <type_traits>
template <class T1, class T2, class T3>
struct ternary {};
template <template <class...> class Template, class... Types>
struct template_struct {
template <class... Args>
struct type: Template<Types..., Args...> {};
};
template <template <class...> class Template, class... Types>
struct template_alias {
template <class... Args>
using type = Template<Types..., Args...>;
};
And now the test:
int main(int, char**) {
using ts0 = template_struct<ternary>; // OK
using ts1 = template_struct<ternary, bool>; // OK
using ts2 = template_struct<ternary, bool, char>; // OK
using ts3 = template_struct<ternary, bool, char, int>; // OK
using ts4 = template_struct<ternary, bool, char, int, double>; // OK
ts0 s0; // OK
ts1 s1; // OK
ts2 s2; // OK
ts3 s3; // OK
ts4 s4; // OK
using ta0 = template_alias<ternary>; // OK
using ta1 = template_alias<ternary, bool>; // OK
using ta2 = template_alias<ternary, bool, char>; // OK
using ta3 = template_alias<ternary, bool, char, int>; // OK
using ta4 = template_alias<ternary, bool, char, int, double>; // OK
ta0 a0; // OK
ta1 a1; // OK
ta2 a2; // OK
ta3 a3; // CLANG, MSVC ERROR: WAIT WHAT ?!?!
ta4 a4; // GCC, CLANG, MSVC ERROR
return 0;
}
The code is available on compiler explorer: https://godbolt.org/z/3ndYMWvfs
QUESTION: What is happening? Which compiler is correct? What does the standard say? Is it a compiler bug?
Aucun commentaire:
Enregistrer un commentaire