我试图理解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> >&)> >’
答案 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);
但是,目前还不清楚为什么你需要使用成员函数,因为它们都没有使用对象的状态。另一个简单的解决方案是首先不使用非静态函数。