没有重新绑定模板的类型定义模板.用作模板类参数的模板

typedef template without template rebind. Use as a template of template class parameter

本文关键字:定义 类型 参数 新绑定 绑定      更新时间:2023-10-16

我想做这样的事情:

template<class T>
class BaseSubscriber {};
template<class T>
class BasePublisher
{
// not working : invalid use of template-name 'BaseSubscriber' without an argument list
typedef BaseSubscriber SubscriberType;
// compiling
typedef BaseSubscriber<T> SubscriberTypeT;
};

template< template<class T> class Subscriber, class Data >
class ClassA:
public Subscriber<Data> 
{
};
template< template<class T> class Publisher, class Data >
class ClassB:
public Publisher<Data>  
{
// Ok, but I want that the type "BaseSubscriber" depends on the template parameter Publisher
void method1(ClassA<BaseSubscriber, Data>&);

// I want something like that. But how to define SubscriberType ?
void method2(ClassA<Publisher<Data>::SubscriberType, Data>&);
// or (SubscriberType only depends on the Publisher, nor on the Data)
void method2(ClassA<Publisher::SubscriberType, Data>&);

// Error : template argument is invalid
void method3(ClassA<Publisher::SubscriberTypeT, Data>&);
};

是否可以定义一些可用于模板参数classASubscriberType?还是有什么解决方法?

如果可能的话,我想保留classA原型。我不想更改它

template<class TSubscriber > classA {};

而且我不能使用 C++11。 非常感谢您的回答。

当你说:

// I want something like that. But how to define SubscriberType ?
void method2(ClassA<Publisher::SubscriberType>);

由于Publisher是一个模板,但您没有向它传递任何参数。

无论如何,这里有一些选项:

在 C++11 中,您可以使用模板别名:

template<class T>
class BasePublisher
{
template<typename U>
using SubscriberType = BaseSubscriber<U>;
};

您还可以使用嵌套类:

template<class T>
class BaseSubscriber {};
template<class T>
class BasePublisher
{
template<class U>
class BaseSubscriber {};
};

或者更改ClassA以使用type成员:

template<class T>
class BasePublisher
{
template<class U>
struct SubscriberType {
typedef BaseSubscriber<U> type;
};
};
template< template<class T> class SubscriberT >
class ClassA {
typedef typename SubscriberT::type Subscriber;
};

或者,有时,如果您不需要别名,继承会起作用:

template<class T>
class BasePublisher
{
template<class U>
struct SubscriberType : BaseSubscriber<U> {};
};

模板别名在 C++03 中是不允许的,尽管它们在 C++11 中。

你的目标是能够做到:

typename BaseSubscriber<A>::SubscriberType<B>

在 C++03 中,您应该使用嵌套类,以便:

template< typename T > struct BasePublisher
{
template< typename U > struct Subscriber
{
typedef BaseSubcriber<U> type;
};
};

现在你可以做类型名 BasePublisher::Subscriber::type;

在 C++11 中,语法为:

template < typename T > struct BasePublisher
{
template< typename U > using SubscriberType = BaseSubscriber<U>;
};

目前还没有多少编译器支持这一点。 虽然你不能做TypeName Typename,但它可能需要另一个Typedef介于两者之间。

如果我正确理解,您希望ClassA获得BaseSubscriber的实例化,例如BaseSubscriber<my_tag>并在BasePublisher的实例化上ClassB。 正确吗?

如果你的答案是肯定的,那么为什么你声明templateClassAClassB的参数为模板,你不想在ClassAClassB中对它做某事,所以它应该是一个类而不是模板化类:

template<class T>
class BasePublisher
{
// compiling
typedef BaseSubscriber<T> SubscriberTypeT;
};
template< class SubscriberT > class ClassA : SubscriberT {};
template< class PublisherT >
class ClassB : PublisherT {
void method1( ClassA<typename PublisherT::SubscriberTypeT> );
};