在使用bind实现调度表的过程中,我尝试用函数模板替换宏。
一旦我开始添加用于返回std::string
或double
的表格,我将非常喜欢模板版本。
宏版本工作正常,但模板版本转储核心。
有人可以解释我做错了吗?谢谢。
CODE
#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;
}
答案 0 :(得分:4)
您的问题在于如何将method
捕获到您的lambda中。您正在通过引用捕获method
,它引用了本地方法参数,即堆栈上的值。在调用函数之前,return std::bind()
不会被执行,此时它将尝试绑定对堆栈变量的引用,这显然不再存在。
您只需将[&method]
更改为[method]
即可按值捕获。