【问题标题】:How to specialize a class template with a template template parameter?如何使用模板模板参数专门化类模板?
【发布时间】:2015-12-22 23:38:34
【问题描述】:

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

#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)。我想在std::vector 上专门化Z 但我对std::vector 的类型模板参数不感兴趣,没关系。此外,我想专注于所有 Collection 类型,其中包含int

这个问题和下面的问题类似,但是他们要么是在尝试专门化一个函数模板

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

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

【问题讨论】:

  • 我不明白你在做什么。如果允许您尝试执行的“专业化”类型,那么在什么情况下会实例化该专业化? Z 的参数是模板,而不是类型。

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


【解决方案1】:

以下代码编译良好:

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

在您的代码中,您给Z 一个模板模板参数,即使这应该仅用于专业化。这就是您的代码无法编译的原因。

【讨论】:

    【解决方案2】:

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

    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&lt;int&gt;C 是类模板,与具体类型的C&lt;int&gt; 不同)。

    如果你的类有模板参数,它是一个类模板,并且你希望你的类对传递给容器的不同类型有不同的行为,你可能应该这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多