0

これが過度に複雑でないことを願っています。しばらくインターネットを検索してみましたが、テンプレートや継承などを扱う多くの Q/A を見つけましたが、見つけたリソースのどれもこの特定の問題を扱っていませんでした:

タイプのベクトルまたはその継承されたクラスstd::vector<T>のみを作成するラッパーを作成したいと思います。std::vector<MyClass>

これは基本的に次のようになります。

Class Base;
Class Derived : Base;

template <Base T> class myVector{
public:
    void add(T);
protected: 
    std::vector<T> list;
}

目標は、次の動作を持つライブラリを持つことができるようにすることです。

Base       A;
Derived    D;
int        i;    

myVector<A> AVector;  // This should work
myVector<D> DVector;  // This should work
myVector<i> iVector;  // This should NOT work

AVector.add(A);  // This should work
AVector.add(D);  // This should work (through polymorphism)

DVector.add(D);  // This should work
DVector.add(A);  // This should not work

上記の質問/例について誰でもコメントできますか? 私の最終的な目標は、C++ で独自の基本的なイベント処理を展開することです。この場合、A は c# EventArgs の類似物になります。B は、特定の EventArgs タイプを許可します。Boost なども同様の機能を持っていることに疑いの余地はありませんが、当面はそのルートを避けたいと思います。

実際には、コードは次のように機能します (インターネット上のどこかで見つけたチュートリアルに基づいています)。

template<EventArgs arg> class Event{
    typedef void (*fptr)(arg);
    std::vector<fptr> listeners;
}


void notifylisteners(arg){
for (typename std::vector<fptr>::iterator iter = listeners.begin(); iter != listeners.end; ++iter)
    (**iter)(arg);  // there should be a check for a valid reference, in case one of the function pointers becomes invalid

宣言

Event<myEventHandlerType> myEvent; 

C# コードと同じように効果的に機能します。

public event myEventHandlerType myEvent;

std::vector に依存しているため、この実装にはテンプレートが必要です。ここで非型パラメーター テンプレートを使用する利点は (それが機能する場合)、特定の eventArg パラメーター型の使用が登録済みのすべてのハンドラーに強制的に渡されることと、コンパイル中にエラーが発生することです。

ご意見やご感想をお待ちしております。

マイケル

4

2 に答える 2

2

C++11 を使用している場合は、std::is_base_of<> および static_assert() にアクセスできます

Base にキャストできない型で myVector が渡された場合に、コンパイラでエラーが発生するようにすることができます。

#include <type_traits>

class Base
{};

class Derived : public Base
{};

template <class T>
class Foo
{
public:
    Foo()
    {
        static_assert (std::is_base_of<Base,T>::value, "Error: Type T not derived from Base");
    }
};

class Lol
{
};


Foo<Derived> foo1;
Foo<Lol> foo2; //Static assert fails

(ここのコンパイラ出力を参照してくださいhttp://ideone.com/NAXSA )

C++11 がサポートされていない場合は、もう少し手間がかかりますが、それでも実行できます。そのhttps://stackoverflow.com/a/4532302/564944についてはこちらをご覧ください

于 2012-07-13T20:56:07.320 に答える
1

あなたの説明が正しく理解できたと思います。これを行う C++ の方法は、継承によるものではなく、継承元の型が渡されることを「強制」することもありませんA。代わりに、ダック タイピングを使用します。アヒルのように見え、アヒルのように歩き、アヒルのように鳴く場合の場合、「公式」タイプに関係なく、アヒルです。

具体的には、単純に任意のタイプmyVector<T>を受け入れます。特定の で呼び出すなど、サポートされていないオブジェクトに対して何かを行おうとすると、コンパイル時に失敗します。TTarg

もちろん、Tサポートが必要な操作の署名を文書化することをお勧めします。つまり、操作が実装するインターフェイスです。

(補足: C++0x の「概念」の概念により、これをコードで表現できたはずですが、標準から削除されました。)

于 2012-07-13T20:27:16.563 に答える