简体   繁体   English

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

[英]How to specialize a class template with a template template parameter?

I'd like to specialize a class template on the type template parameter of the template template parameter. 我想专门针对模板模板参数的类型模板参数指定类模板。 Is it possible? 可能吗? If yes, what is the syntax? 如果是,语法是什么?

#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

Motivation: Let's assume that the template template parameter denotes Collections (eg std::vector , std::deque ). 动机:假设template template参数表示Collections(例如std::vectorstd::deque )。 And I want to specialize Z on std::vector but I am not interested about the type template parameter of std::vector , that's OK. 我想专门Zstd::vector ,但我没有兴趣有关的类型模板参数std::vector ,那也无妨。 Also I want to specialize on all Collection types, which holds an int . 我也想专门研究所有具有int Collection类型。

This question is similar to the following questions, but they are either trying to specialize a function template 该问题与以下问题类似,但它们正在尝试专用于功能模板

or they are trying to specialize not on the template template parameter 还是他们试图专门针对模板template参数

or there's no template template parameter in the primary template 或主模板中没有模板template参数

The following code compiles fine: 以下代码可以正常编译:

#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
}

In your code you give Z a template template parameter, even though that should be done for the specialization only. 在代码中,您为Z了一个模板模板参数,即使该参数仅应用于专业化也是如此。 That's why your code does not compile. 这就是为什么您的代码无法编译的原因。

This cannot work because in your code: 这无法工作,因为在您的代码中:

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

Z expects class template as a parameter. Z希望将类模板作为参数。

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

Here you are are not specializing any of it's template arguments and trying to pass C<int> which is not a class template ( C is a class template and is different than C<int> which is concrete type). 在这里,您没有专门使用任何模板参数,而是尝试传递不是类模板的C<int>C是类模板,与具体类型的C<int>不同)。

If your class has template parameter which is a class template and you want your class to behave differently for different types passed for the container you probably should do something like: 如果您的类具有template参数,这是一个类模板,并且您希望类针对传递给容器的不同类型表现不同,则可能应该执行以下操作:

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();
    //...
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM