使用boost :: bind在std :: map中调用functor

时间:2013-07-25 10:25:53

标签: c++ boost bind functor

我遇到了麻烦,我无法在SO上找到解决方案。我花了一段时间来搞清楚,所以我想我会发布它,以防它对其他人有用

问题: 我有一组不同类型的仿函数,我想将它存储在std :: map中,然后稍后调用类似switch语句/ factory。

class Foo {
public:
    void operator() (int x) {
        std::cout << "In foo" << x << std::endl;
    }
};
class Bar {
public:
    void operator() (int x) {
        std::cout << "In Bar" << x << std::endl;
    }
};

地图看起来像

std::map<int,boost::function<void(int)>> maps;

插页看起来像

maps.insert(std::make_pair(1,boost::bind(&Foo::operator(),Foo(),_1)));

你可以称之为

auto iter = maps.find(1);
iter->second(123);

看看这个解决方案,它很简单,只有一个班轮,而心理体操试图解决它 - 哦,好吧:)

我最初想要做的是存储boost :: signals2 :: signal对象,这样我就可以在地图中链接一组工厂,但我从来没有弄明白。那么对于一个问题,我如何将它们存储在地图中呢?

std::map<std::string,boost::signals2::signal<void(int)>> m_factory;
// Create the object I want to store
boost::signals2::signal<void(int)> sig;
sig.connect(Foo());
// This fails
m_factory.insert(std::make_pair("Blah",sig));

但我得到

std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::insert(std::pair<const _Kty,_Ty> &&)' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'std::pair<_Ty1,_Ty2> &&

编辑进一步简化了示例

编辑2 - 修复我在参考资料中声明地图的错误

除此之外,这似乎工作正常

typedef boost::signals2::signal<void(int)> Signal;
m_factory["Blah"] = Signal().connect(Foo());

我认为逻辑上与make_pair相同?

1 个答案:

答案 0 :(得分:1)

boost :: signals是不可复制的,这使得它们不适合与std容器一起使用。你应该在信号中使用指针(可能是智能指针),如

typedef boost::signals2::signal<void(int)> sig;
typedef std::shared_ptr<sig> pSig;
typedef std::map<int, pSig> map_sig;

void f(int){}

int main(){
    pSig s(new sig);
    s->connect(f);

    map_sig m;
    m.insert( map_sig::value_type(1, s) );
}

(您可以尝试代码here)。