0

私はここの壁に頭をぶつけています...これに対する解決策を見つける方法がわからないので、この質問のタイトルをどのように表現するかわかりませんでした。

各コンポーネントタイプ(Position、Direction、Meshなど)のすべてのインスタンスのマップを含む基本テンプレートクラス(Component)があります。マップをトラバースし、インスタンスごとにvoidメンバー関数(Iterate関数の引数として提供)を呼び出す「Iterate」関数を作成するのに問題があります。関数ポインタを使用することになっていると確信していますが、オンラインで見つけたすべての例は、グローバル関数または非テンプレートクラス用です。

これが基本テンプレートクラスです

typedef unsigned long uuid;

template <class T>
class Component {

public:
    static std::map<uuid, T*> IDS;
    static typename std::map<uuid, T*>::iterator Iterator;
    static T* Create(uuid fID) {
        Component<T>::IDS[fID] = new T(fID);
        return Component<T>::IDS[fID];
    };

    static void Iterate(); //how do I add in void function pointers?
    static bool ifExists(uuid fID);
};

template <typename T>
std::map<uuid, T*> Component<T>::IDS;

template <typename T>
typename std::map<uuid, T*>::iterator Component<T>::Iterator;

template <typename T>
void Component<T>::Iterate() {
    for(Iterator = IDS.begin(); Iterator != IDS.end(); Iterator++) {
        //This references the instance that performs the given function
        //(*Iterator).second
    }
}

テンプレートで使用されるコンポーネントの例を次に示します。

class COM_Position {
    float x, y, z;
public:
    COM_Position(uuid fID);
    uuid ID;
    void Set(float fX, float fY, float fZ);
    void Display();
};

COM_Position::COM_Position(uuid fID) : ID(fID) {
    x = 0; y = 0; z = 0;
}

void COM_Position::Display() {
    printf("%lu : (%f, %f, %f)", ID, x, y, z);
}

typedef Component<COM_Position> Position;

各インスタンスに適用できる引数として関数ポインターを受け取る反復関数を作成するにはどうすればよいですか(たとえば、インスタンスごとにDisplayを呼び出す)。こんなことができるようになりたいです。

int main() {
    for(int ii = 0; ii < 4; ii++) {
        Position::Create(ii);
    }

    /*
    This is what I am aiming for; a clean iterator function
    Position::Iterate(Display());
    */
}

これが不可能な場合は、マクロを使用してこれをシミュレートできることを知っています...

4

1 に答える 1

1

このようなもの?

template <typename T>
void Component<T>::Iterate(void (T::*method)() ) {
    for(Iterator i= IDS.begin(); i != IDS.end(); i++) {
        (i->second->*method)();
    }
}

そして繰り返します:

Position::Iterate( &COM_Position::Display );

編集:いくつかのニートオーバーロード:

また、C ++ 0xの可変個引数テンプレートを使用すると、いくつかの一般的なメソッドを使用できます。私はそれをテストしませんでしたが、それは有望に見えます:

template <typename T, typename... Args>
void Component<T>::Iterate(void (T::*method)(Args... args), Args&&... params) {
    for(Iterator i= IDS.begin(); i != IDS.end(); i++) {
        (i->second->*method)(std::forward<Args>(params)...);
    }
}

ほとんどの関数とファンクターは、次のもので使用できます。

template <typename T, typename F>
void Component<T>::Iterate( F func ) { // using generic functor 
    for(Iterator i= IDS.begin(); i != IDS.end(); i++) {
        func(i->second->*method);
    }
}
于 2012-05-22T03:11:30.147 に答える