类中的std :: function初始化

时间:2017-05-30 14:00:05

标签: c++ c++11 std-function

我试图理解std :: function是如何工作的,我无法编译这个,我不明白为什么。我认为这与在类中使用std :: function有关,因为没有类(在全局范围内定义的map)它可以工作。

这是我收到的错误消息:

  

functor.cc:37:9:错误:无法转换 WeekOfYear Production regression 1 1 202612 250517.6 2 2 245633 253864.1 3 3 299653 257210.5 4 4 252612 260557.0 5 5 299633 263903.5 6 6 288993 267249.9 7 7 254653 270596.4 8 8 288612 273942.9 9 9 277733 277289.3 10 10 245633 280635.8 11 11 NA 283982.3 12 12 NA 287328.7 ---- 51 51 NA 417840.9 52 52 NA 421187.4   ‘{{"A", ((C*)this)->C::f}, {"B", ((C*)this)->C::g}, {"C", ((C*)this)->C::h}}’来   ‘<brace-enclosed initializer list>’

示例代码(没有意义,但它代表我遇到的问题):

‘std::map<std::__cxx11::basic_string<char>, std::function<bool(const
  std::vector<std::__cxx11::basic_string<char> >&)> >’

1 个答案:

答案 0 :(得分:4)

std::function<bool(const std::vector<std::string>&)

该函数对象类型只能包含具有签名bool(const std::vector<std::string>&)的函数。但是,尝试使用的函数都没有这样的签名,因为它们是(非静态)成员函数。此外,您必须显式使用address-of运算符来获取指向成员函数的指针,并且名称必须完全限定,如下所示:&C::f

您可以将this绑定到成员函数,这将导致函数对象具有适当的签名:

std::map<std::string, std::function<bool(const std::vector<std::string>&)> >  funcMap {
    {"A", std::bind(&C::f, this, std::placeholders::_1)},
    {"B", std::bind(&C::g, this, std::placeholders::_1)},
    {"C", std::bind(&C::h, this, std::placeholders::_1)}
                           ^ we bind this pointer to the function object
};

您也可以使用lambda。绑定函数和lambdas大多只是编写相同内容的两种方法。

或者,您可能实际上只想存储成员函数而不是函数对象中的对象指针。在这种情况下,您的函数对象的类型以及您调用它的方式都是错误的。这可行:

std::map<std::string, std::function<bool(C*, const std::vector<std::string>&)> >  funcMap {
//                                       ^ note the pointer argument for this
    {"A", &C::f},
    {"B", &C::g},
    {"C", &C::h}
};

// call
c.funcMap["A"](&c, v);
//              ^ The object on which the member function is called. 
//                It doesn't necessarily have to be the same whose funcMap is used.

在这种情况下,您并不需要std::function。成员函数指针的映射就足够了。调用成员函数指针的语法与使用函数对象略有不同:

std::map<std::string, bool (C::*)(const std::vector<std::string>&) >  funcMap {
    {"A", &C::f},
    {"B", &C::g},
    {"C", &C::h}
};

// call
(c.*c.funcMap["A"])(v);

但是,目前还不清楚为什么你需要使用成员函数,因为它们都没有使用对象的状态。另一个简单的解决方案是首先不使用非静态函数。