如何使用模板模板参数专门化 class 模板?
How to specialize a class template with a template template parameter?
我想在模板模板参数的类型模板参数上专门化一个 class 模板。可能吗?如果是,语法是什么?
#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::vector
、std::deque
)。我想在 std::vector
上专门研究 Z
,但我对 std::vector
的类型模板参数不感兴趣,没关系。我还想专注于所有 Collection 类型,它包含 int
.
这个问题类似于下面的问题,但它们要么试图特化一个函数模板
- Specialize a template with a template
或者他们试图不专注于模板模板参数
- Specialization and template template parameters
或者主模板中没有模板模板参数
- Templated class specialization where template argument is a template
这不起作用,因为在您的代码中:
template<template<class> class C>
struct Z : std::false_type {};
template<>
struct Z<X> : std::true_type {};
Z
需要 class 模板作为参数。
template <template<class> class C>
struct Z<C<int>> {};
在这里你没有专门化它的任何模板参数并试图传递 C<int>
这不是 class 模板(C
是一个 class 模板并且不同于具体类型 C<int>
。
如果你的 class 有一个模板参数,它是一个 class 模板,你希望你的 class 对传递给容器的不同类型表现不同,你可能应该这样做:
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();
//...
};
以下代码可以正常编译:
#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
提供了一个模板模板参数,即使这样做只是为了专业化。这就是您的代码无法编译的原因。
我想在模板模板参数的类型模板参数上专门化一个 class 模板。可能吗?如果是,语法是什么?
#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::vector
、std::deque
)。我想在 std::vector
上专门研究 Z
,但我对 std::vector
的类型模板参数不感兴趣,没关系。我还想专注于所有 Collection 类型,它包含 int
.
这个问题类似于下面的问题,但它们要么试图特化一个函数模板
- Specialize a template with a template
或者他们试图不专注于模板模板参数
- Specialization and template template parameters
或者主模板中没有模板模板参数
- Templated class specialization where template argument is a template
这不起作用,因为在您的代码中:
template<template<class> class C>
struct Z : std::false_type {};
template<>
struct Z<X> : std::true_type {};
Z
需要 class 模板作为参数。
template <template<class> class C>
struct Z<C<int>> {};
在这里你没有专门化它的任何模板参数并试图传递 C<int>
这不是 class 模板(C
是一个 class 模板并且不同于具体类型 C<int>
。
如果你的 class 有一个模板参数,它是一个 class 模板,你希望你的 class 对传递给容器的不同类型表现不同,你可能应该这样做:
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();
//...
};
以下代码可以正常编译:
#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
提供了一个模板模板参数,即使这样做只是为了专业化。这就是您的代码无法编译的原因。