将std :: function <void(string,string)=“”>转换为通用的std :: function <void()> </void()> </void(string,>

时间:2011-10-24 15:44:28

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

我正在尝试使用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");

3 个答案:

答案 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绑定到arg1arg2的值,并且更改{{}中使用的对象的值1}}稍后不会影响调用bind时使用的值。有一种解决方法:

f()

这会导致f保持对对象的引用,而不仅仅是调用string arg1,arg2; function<void()> f = bind(f1,std::ref(arg1),std::ref(arg2)); // f = [&,f1] { f1(arg1,arg2); }; 时使用的静态值。您现在可以为bindarg1分配新值,并且在调用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));
}