4

私はこのようなことをしたい:

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>&);
};

テンプレートパラメータSubscriberTypeに使用できるものを定義することは可能ですか?classAまたは、回避策はありますか?

classAできれば試作品を残しておきたいです。変更したくない

template<class TSubscriber > classA {};

そして、私はC++11を使用できません。ご回答ありがとうございます。

4

3 に答える 3

3

あなたが言うとき、あなたが何を意味するのか少し混乱しています:

// 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> {};
};
于 2012-11-07T10:03:28.737 に答える
1

テンプレート エイリアスは、C++11 では使用できますが、C++03 では使用できません。

あなたの目標は、次のことができるようになることです:

typename BaseSubscriber<A>::SubscriberType<B>

C++03 では、次のようにネストされたクラスを使用する必要があります。

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

そして今、おそらく typename BasePublisher::Subscriber::type; を実行できます。

C++11 では、構文は次のようになります。

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

それをサポートするコンパイラはまだ多くありません。ただし、 typename typename を実行できないため、間に別の typedef が必要になる場合があります。

于 2012-11-07T10:02:27.877 に答える
0

私が正しく取得した場合、たとえばのClassAインスタンス化を取得し、 のインスタンス化を取得する必要があります。それが正しいか?BaseSubscriberBaseSubscriber<my_tag>ClassBBasePublisher

あなたの答えが「はい」の場合、 and の引数をテンプレートとして宣言する理由は、templateorで何かをしたくないため、テンプレート化されたクラスではなくクラスにする必要があります。ClassAClassBClassAClassB

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> );
};
于 2012-11-07T10:13:20.690 に答える