如何使用模板模板参数专门化类模板?

时间:2015-12-22 23:38:34

标签: c++ templates template-specialization partial-specialization

我想在模板模板参数的类型模板参数上专门化一个类模板。可能吗?如果是,语法是什么?

#include <type_traits>

template <typename T>
struct X {};

// primary template
template<template<class> class C>
struct Z : std::false_type {};

// specialization on the template template parameter
template<>
struct Z<X> : std::true_type {}; // OK

// specialization on the type template parameter of the
// template template parameter
template <template<class> class C>
struct Z<C<int>> {}; // ERROR

动机:我们假设模板模板参数表示集合(例如std::vectorstd::deque)。我想在Z上专注std::vector,但我对std::vector的类型模板参数不感兴趣,这没关系。另外,我想专注于所有Collection类型,它们包含int

此问题类似于以下问题,但他们要么尝试专门化功能模板

或者他们试图不专注于模板模板参数

或主模板中没有模板模板参数

2 个答案:

答案 0 :(得分:2)

以下代码编译良好:

null

在您的代码中,您为#include <type_traits> template <typename T> struct X {}; // primary template, no template template parameter template<typename T> struct Z : std::false_type {}; // specialization on the template template parameter with arbitrary T template<typename T> struct Z<X<T>> : std::true_type {}; // here's where you need the template template parameter template <template<class> class C> struct Z<C<int>> : std::true_type {}; int main() { static_assert(!Z<Z<double>>::value, "" ); static_assert( Z<Z<int >>::value, "" ); static_assert( Z<X<double>>::value, "" ); // static_assert( Z<X<int >>::value, "" ); // error: ambiguous // partial specialization } 提供了一个模板模板参数,即使这只应该用于专门化。这就是你的代码无法编译的原因。

答案 1 :(得分:1)

这不起作用,因为在您的代码中:

template<template<class> class C>
struct Z : std::false_type {};
template<>
struct Z<X> : std::true_type {};

Z期望将类模板作为参数。

template <template<class> class C>
struct Z<C<int>> {};

在这里,你不是专门研究它的任何模板参数,并试图传递不是类模板的C<int>C是一个类模板,不同于C<int>具体类型)。

如果您的类具有模板参数,该模板参数是一个类模板,并且您希望您的类对于为容器传递的不同类型的行为不同,您可能应该执行以下操作:

template<template <typename> class Container,typename Element>
struct MyStruct
{
    Container<Element> generic_elements;
    // ...
};

template<template <typename> class Container>
struct MyStruct<Container,int>
{
    Container<int> special_int_container;
    void special_int_things();
    //...
};