2

有一个像A这样的类,有没有办法将它应用到像B这样的模板,T2设置为某种类型C?但是没有创建另一个继承自 A 的模板类。

template<typename T1, typename T2>
class A
{ };

template<template <typename T1> class T3>
class B
{ };
4

3 回答 3

3

使用 C++11 使用模板别名有效:

template<typename T1, typename T2>
class A
{ };

template<template <typename T1> class T3>
class B
{ };

class C
{ };

template< typename T > using A1 = A< T, C >;

int main()
{
    B< A1 > b;
}

如果没有 C++11,您可能已经知道:

template< typename T > class A1 : A< T, C > {};
于 2013-09-13T17:05:35.283 回答
2

我将提出一个替代解决方案:不要使用模板模板参数。

如果你写:

template <typename T> struct B {};

然后它可以与A<int, int>C<3>什至plain一起使用D

虽然可以使用模板模板参数,但这通常是个坏主意。您应该将类​​的模板参数视为实现细节并应用黄金法则:不要依赖实现细节。

如果您需要以某种方式访问​​该类型,请使用关联类型(aka T::AssociatedType)或特征BTraits<T>::AssociatedType)。

编辑:处理模板模板参数的多个实例化。

假设我们要“擦除”这样一个类的模板模板参数:

template <template <typename> class A>
struct Something {
    template <typename T>
    void doit() { A<T>::doit(); }
};

C++ 标准分配模型是使用内部rebind结构:

template <typename T>
struct Simple {
    template <typename U>
    struct rebind { typedef Simple<U> type; };
};

template <typename T0, typename T1>
struct Multi {
    template <typename U>
    struct rebind { typedef Multi<U, T1> type; };
};

template <typename A>
struct Something {
    template <typename T>
    void doit() { typedef typename A::rebind<T>::type B; B::doit(); }
};

请注意如何使用复杂的计算,rebind并且没有什么会迫使您盲目地传递作为参数接收的类型。

而另一种(类似的)解决方案是要求一个工厂(也就是不能使用传递给自己的对象,但它可以构建有用的对象);为了便于使用,C++ 容器询问它们的分配器,它们既可以在自身中使用,也可以用于其他类型的工厂。

于 2013-09-13T17:56:25.220 回答
1

是的,你可以使用 C++11 的别名模板来做到这一点:

template <typename T>
using AA = A<T, C>;

B<AA> b;

活生生的例子

于 2013-09-13T16:56:38.227 回答