在此答案的底部,有更多关于如何解决此类问题的信息和示例。
但为了更具体地解决您的问题,无法对模板模板参数的参数数量进行部分专业化。至少,不是你想要的方式......
通常对类型进行部分特化。它可以为模板参数完成,但在这种情况下,不同的特化必须命名一个模板,并且每个特化必须为具有相同数量参数的模板完成。
这可能解释了为什么不允许您尝试定义专业化的方式...
也就是说,可以对具有typename 参数的模板进行特化,以用于容器 类型。也就是说,模板的参数类型已经'declared'。 我故意使用“声明”这个词......
确实,正如我在“使用模板模板函数获取模板参数数量”的答案中所证明的那样 here,可以注入“随机” 不实例化模板。
这个特性可以用许多不同的方式来定义模板的特化,例如:
这个答案底部的代码(取自我的另一个答案),显示了一种利用该语言的工具的简单方法提供...
° 怎么能做到这样的专业化?
但是为了防止你到处寻找一些工作代码,下面的代码是一个解决方案,可以用来根据模板模板参数来专门化一个模板。
它应该是不言自明的......
// Helper to make the static_assert 'name-dependent'.
template<typename...> using AlwaysFalse = std::false_type;
// Primary template should only signal the error...
template<typename Trait>
struct ImplSelect {
static_assert(
AlwaysFalse<Trait>::value,
"Missing specialization..."
);
};
// Specialization for a template with one type parameter.
template<template <typename> class Trait, typename T>
struct ImplSelect<Trait<T>> { using Type = Trait<int>; };
// Specialization for a template with two type parameters.
template<template <typename, typename> class Trait, typename T, typename U>
struct ImplSelect<Trait<T, U>> { using Type = Trait<int, int>; };
/* [ Note ] These are ONLY forward declarations.
* They aren't instatiated within this code.
*/
template<typename T> struct Victim1;
template<typename T, typename U> struct Victim2;
/* [ Note ] Opaque type tags (forward declarations).
* Allows for further tag dispatching if desired.
*/
struct Tag1; struct Tag2;
/* Selection of Victim1<int> and Victim2<int, int>.
* Not instantiated yet...
*/
using Impl1 = typename ImplSelect<Victim1<Tag1>>::Type;
using Impl2 = typename ImplSelect<Victim2<Tag1, Tag2>>::Type;
享受吧!