4

2つのクラスがあるとしましょう:

class A {}

class B : public A {}

そしてstd::function、タイプA のすべてを受け取りますが、 Aから継承するクラスを受け取る割り当てメソッドを使用したい( Bなど)。

void myFun(B bbbb) {}

std::function<void(A)> blah = std::bind(myFun, _1);

コンパイラは暗黙的にダウンキャストするだけではないため、これは明らかに機能しません。

しかし、どうすればこのようなことができますか? 基本的に、いくつかの基本的な std::function 型のマップを保持したいと思います。マップされた各値では、Bstd::functionのような派生型を保持します。

キャスト演算子をプレースホルダーにバインドする方法はありますか?

4

1 に答える 1

4

OK、最後に回避策を実行しました。
コンパイラは暗黙的にダウンキャストを許可しないため、キャスト メソッドをバインドしました。
したがって、すべてを汎用的かつテンプレート化するために、次のようになります。

まず、関数の引数の型を取得するヘルパー クラス:

template <typename T>
class GetFunctionArgumentVal;

template <class T, typename U >
class GetFunctionArgumentVal<std::function<U(T)>>
{
public:
    typedef T arg;
    typedef U returnVal;
};

次に、static_cast を使用してキャストするキャスト演算子 (コンパイル時の型の安全性を維持する) が、派生クラスを使用して関数を呼び出します。

template <typename FUNCTION, typename BASE>
void castAndCall(FUNCTION bf, BASE& temp) 
{
    bf(static_cast< GetFunctionArgumentVal<FUNCTION>::arg >(temp));
}

使用例:

class A {};

class B : public A {};

class C : public A {};

void targetB(B& temp) 
{

}

void targetC(C& temp) 
{

}

    std::function<void(A &)> af;
    std::function<void(B &)> bf = targetB;
    std::function<void(C &)> cf = targetC;

    B b;
    C c;

    af = std::bind(castAndCall<decltype(bf),A>,bf,std::placeholders::_1);
    af(b);

    af = std::bind(castAndCall<decltype(cf),A>,cf,std::placeholders::_1);
    af(c);
于 2013-08-12T07:18:29.897 に答える