考虑以下C ++代码:
#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");
在实例化B<A>
中,参数A
的模板参数数量(其中有两个:T, U
)与预期的模板参数数量之间存在明显的不匹配。 X
中的模板模板参数B
(只有一个预期参数:V
)。但是,从直观上看,这种不匹配似乎是良性的,因为U
的第二个参数A
是可选的,并且具有默认值,因此实例A<int>
的格式正确。因此,将A
作为模板模板参数X
的参数传递似乎是安全的,该模板模板参数只能用一个模板参数实例化。的确,此代码可使用GCC成功编译。但是它对Clang和MSVC失败,抱怨参数数量不匹配。如果模板模板参数只需要一个(或任何固定数量)参数,但相应的参数是可变参数,并且可以接受任意数量的参数,则会发生类似的问题:
#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");
同样,此代码可使用GCC成功编译,但不能使用Clang或MSVC编译。 C ++标准的最新草案对此主题有何看法,以及哪个编译器在形式上正确?