0

Consider the following C++ code:

#include <type_traits>

template<typename T, typename U = T>
struct A { 
    typedef U type;
};

template<template<typename V> typename X>
struct B : X<int> { };

static_assert(std::is_same<int, typename B<A>::type>(), "assert");

In instantiation B<A> there is an apparent mismatch between the number of template parameters of the argument A (there are two of them: T, U) and the expected number of template parameters of the template template parameter X of B (there is only one expected parameter: V). But, intuitively, this mismatch seems benign, because the second parameter U of A is optional and has a default value, and so, for example, the instantiation A<int> is well-formed. Hence, it seems safe to pass A as an argument for the template template parameter X that can be instantiated with only one template argument. Indeed, this code compiles successfully with GCC. But it fails with Clang and MSVC, complaining about mismatch of the number of parameters. A similar issue occurs if the template template parameter expects only one (or any fixed number) of parameters, but the corresponding argument is variadic and can accept any number of arguments:

#include <type_traits>

template<typename... T>
struct A { 
    static constexpr auto value = sizeof...(T);
};

template<template<typename V> typename X>
struct B : X<int> { };

static_assert(B<A>::value == 1, "assert");

Again, this code compiles successfully with GCC, but not with Clang or MSVC. What does the latest draft of the C++ Standard say on this topic, and which compiler is formally correct?

Vladimir Reshetnikov
  • 11,750
  • 4
  • 30
  • 51

0 Answers0