简体   繁体   English

如何将此宏转换为功能模板?

[英]How do I convert this macro to a function template?

In the process of implementing a dispatch table with bind, I am trying to replace a macro with a function template . 在用bind实现调度表的过程中,我试图用功能模板替换宏

I will strongly prefer a template version, once I start adding tables for returning std::string or double . 一旦开始添加表以返回std::stringdouble ,我将强烈希望使用模板版本。

The macro version works fine, but the template version dumps core. 宏版本工作正常,但模板版本转储核心。

Can someone explain what I am doing wrong? 有人可以解释我在做什么错吗? Thank you. 谢谢。

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;
}

Your problem is with how you capture method into your lambda. 您的问题在于如何将method捕获到lambda中。 You are capturing method by reference, which is referencing the local method parameter, a value on the stack. 您正在通过引用捕获method ,该引用是引用本地方法参数(堆栈中的一个值)。 The return std::bind() isn't executed until the function is invoked, at which point it will attempt to bind a reference to a stack variable, which obviously no longer exists. 在调用该函数之前,不会执行return std::bind() ,此时它将尝试将引用绑定到一个显然不存在的堆栈变量。

You just need to change [&method] to [method] to capture by value. 您只需要将[&method]更改为[method]即可按值捕获。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM