2

バインドでディスパッチ テーブルを実装する過程で、マクロを関数テンプレートに置き換えようとしています。

std::stringまたはを返すためのテーブルを追加し始めたら、テンプレート バージョンを強く好みdoubleます。

マクロ バージョンは問題なく動作しますが、テンプレート バージョンではコア ダンプが発生します。

誰かが私が間違っていることを説明できますか? ありがとうございました。

コード

#include <functional>
#include <iostream>
#include <map>

struct Integer
{
    virtual int getInt() const = 0;
};

struct IntImpl : public Integer
{
    virtual int getInt() const { return 42; }
};

typedef std::function<int()>                               IntFunction;
typedef std::function<IntFunction( Integer const& inst )>  IntLambda;

#define USE_MACRO

#ifdef USE_MACRO
#define MP(A,B) \
    std::make_pair( A, []( Integer const& inst ) { \
                return std::bind( B, std::cref( inst )); \
            } )
#else
template<typename L,typename T,typename M>
std::pair<std::string,L>
MP( std::string const& str, M method)
{
    return std::make_pair( str, [&method]( T const& inst ) {
        return std::bind( method, std::cref( inst ));
        } 
    );
}
#endif

static std::map<std::string,IntLambda> const g_intTbl =
{
#ifdef USE_MACRO
    MP( "getInt", &Integer::getInt )
#else
    MP<IntLambda,Integer>( "getInt", &Integer::getInt )
#endif
};

int
main( int argv, char* argc[] )
{
    IntImpl x;
    std::cerr << g_intTbl.find("getInt")->second( x )() << std::endl;
}
4

1 に答える 1

4

method問題は、ラムダにキャプチャする方法にあります。methodスタック上の値であるローカルメソッドパラメーターを参照している参照によってキャプチャしています。return std::bind()関数が呼び出されるまで実行されません。関数が呼び出されると、明らかに存在しないスタック変数への参照をバインドしようとします。

値でキャプチャするように変更[&method]するだけです。[method]

于 2013-01-07T01:09:01.290 に答える