我正在尝试使用c ++ 0x(在gcc 4.5下)的somme功能:
我知道在编译时指定参数时可以将std::function<void(string, string)>
转换为std::function<void()>
;但是在运行时提交参数是否可能?
#include <iostream>
#include <utility>
#include <string>
using namespace std;
using namespace placeholders;
class Print{
public:
void print1(string s1, string s2){ cout<<"s1 : "<<s1<<" s2 : "<<s2<<endl;}
void print2(string s1){ cout<<"s1 : "<<s1<<endl;}
};
Print p = Print();
function<void(string, string)> f1(bind(&Print::print1, &p, _1, _2));
function<void()> f = f1;
我收到了这些错误:
/usr/include/c++/4.5/functional:2103:6: instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = std::function<void(std::basic_string<char>, std::basic_string<char>)>, _Res = void, _ArgTypes = {}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<void()>::_Useless]’
../src/Cpp0x_test.cpp:345:34: instantiated from here
/usr/include/c++/4.5/functional:1713:9: error: no match for call to ‘(std::function<void(std::basic_string<char>, std::basic_string<char>)>) ()’
/usr/include/c++/4.5/functional:2111:5: note: candidate is: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void, _ArgTypes = {std::basic_string<char>, std::basic_string<char>}]
其实我需要这样做:
function<void(string, string)> f1(bind(&Print::print1, &p, _1, _2));
function<void(string)> f2(bind(&Print::print2, &p, _1));
function<void()> fx1 = f1;
function<void()> fx2 = f2;
std::vector<function<void()> > vec;
vec.push_back(fx1);
vec.push_back(fx2);
//then, later
function<void()> call1 = vec[0];
function<void()> call2 = vec[1];
call1("test1", "test2");
call2("test3");
答案 0 :(得分:3)
这个问题没有意义。
我知道转换
std::function<void(string, string)>
是可能的 在编译时指定参数时到std::function<void()>
; 但是在运行时提交参数是否可能?
如果您正在谈论这样做以在编译时设置参数:
string arg1,arg2;
function<void()> f = bind(f1,arg1,arg2); // f = [=] { f1(arg1,arg2); };
这实际上是在运行时进行绑定。无论这些参数在调用bind时具有什么值,即使它们是在运行时设置的,例如,从用户输入设置,调用f()
也将使用这些运行时值。
也许您的意思是上面的代码在调用绑定时将f1
绑定到arg1
和arg2
的值,并且更改{{}中使用的对象的值1}}稍后不会影响调用bind
时使用的值。有一种解决方法:
f()
这会导致f保持对对象的引用,而不仅仅是调用string arg1,arg2;
function<void()> f =
bind(f1,std::ref(arg1),std::ref(arg2)); // f = [&,f1] { f1(arg1,arg2); };
时使用的静态值。您现在可以为bind
和arg1
分配新值,并且在调用arg2
时将使用新值。请注意,您必须确保f()
所持有的引用仍然有效,并且只要仍然可以调用f
,就不会成为悬空引用。
f
答案 1 :(得分:2)
它可能使用bind以及:
string arg1, arg2;
function<void()> f(bind(f1, arg1, arg2));
f(); // calls f1(arg1, arg2) with their values at the time of bind
答案 2 :(得分:1)
让我们看看我是否理解你的要求。
为什么不将参数存储在向量而不是函数中?
std::vector<std::tuple<std::string,std::string>> v;
v.push_back(std::make_tuple("a", "b")); // repeat
// Later that day...
for(auto& t : v) {
f(get<0>(t), get<1>(t));
}