2015-08-31 2 views
2

Я пытаюсь создать вектор std :: function, а затем передать этот вектор функции. Мне также нужно передать аргументы объектам функции, поэтому я использую std :: bind. Вот код:Проблема в передаче аргумента std :: function для вектора функций

#include <functional> 
#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

void execute(vector<function<void (int)>>& fs) { 
    for (auto& f : fs) 
     f(); 
} 

void func(int k) { 
    cout << "In func " << k << endl; 
} 

int main() 
{ 
    int i = 1; 
    vector<function<void (int)>> x; 
    auto f1 = bind(func, i); 
    //f1(); // this does call intended function 
    x.push_back(f1); 

    execute(x); 
} 

, но это дает следующее сообщение об ошибке:

 
function_tmpl.cpp: In function ‘void execute(std::vector >&)’: 
function_tmpl.cpp:14:5: error: no match for call to ‘(std::function)()’ 
    f(); 
    ^
In file included from function_tmpl.cpp:1:0: 
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2142:11: note: candidate is: 
    class function 
     ^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: _Res std::function::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {int}] 
    function:: 
    ^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/functional:2434:5: note: candidate expects 1 argument, 0 provided 

Если я позвоню F() внутри основной(), который работает хорошо, это означает, что функция связана с аргументами , но это не работает, когда передается другой функции в качестве аргумента

+1

'' функция принимает только функции, которые принимают 'int'. При вызове 'f()' отсутствует 'int'. Либо измените его на 'function ' или используйте 'f (0)'. – nwp

+0

@nwp, будет ли std :: bind не связывать аргументы с функциональным объектом? – DKR

+0

Он делает, но 'function ' все еще требует 'int'. После того, как вы привязали функцию 'int' к функции, функция bound больше не требует' int', поэтому теперь она имеет функцию подписи '. – nwp

ответ

0

е имеет тип функции < недействительным (INT) > & поэтому компилятор ожидает, что вы предоставить ар arameter, как это: е (1)

+0

'@ ZunTzu', будет std :: bind не связывать аргументы с объектом функции? – DKR

+0

Это верно для f1, но не для f, которое статически определяется как принятие одного параметра. – ZunTzu

2

Вы используете вектор недействительных функций с одним Int аргумент: vector<function<void (int)>>, но вы на самом деле толкает void(void) функции. Все, что вам нужно сделать, это изменить тип элемента вектора на vector<function<void (void)>>. Bind работает примерно так:

Дано:

void f1(int i) { printf("%d", i); } 

bind(f1, 1) возвращает новую функцию f2:

void f2() 
{ 
    f1(1); 
} 

и так как вы подталкивают f2, вектор должен хранить void(void) функции.

+0

'@ perreal' Я не нажимаю' void (void) 'функции. Функция ограничена аргументом int: 'auto f1 = bind (func, i);' – DKR

+0

правильный, но тип элемента вектора неверен, поскольку вы нажимаете связанные функции, которые не принимают аргументы. Таким образом, функции, которые вы нажимаете, имеют разные типы, чем оригинальные функции. – perreal

+0

'@ perreal' может быть, я что-то пропустил, но связанная функция i.e func, принимает аргумент? – DKR

1

После связывания тип функции стал void(). Поэтому измените тип vector на vector<function<void()>>, вы получите его.

#include <functional> 
#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

void execute(vector<function<void()>>& fs) { 
    for (auto& f : fs) 
     f(); 
} 

void func(int k) { 
    cout << "In func " << k << endl; 
} 

int main() 
{ 
    int i = 1; 
    vector<function<void()>> x; 
    auto f1 = bind(func, i); 
    x.push_back(f1); 

    execute(x); 
} 

результат:

In func 1 

LIVE

1

Возвращаемый тип std::bind не определен. Следовательно, вы не можете ожидать, что std::bind вернет переменную того же типа, что и std::function<void(int)>. Используйте decltype и шаблоны для решения.

Here is an example

#include <functional> 
#include <iostream> 
#include <string> 
#include <vector> 
using namespace std; 

template <typename T> 
void execute(vector<T>& fs) { 
    for (auto& f : fs) 
     f(); 
} 

void func(int k) { 
    cout << "In func " << k << endl; 
} 

int main() 
{ 
    int i = 1; 
    auto f1 = bind(func, i); 
    vector<decltype(f1)> x; //deduce type of f1 
    x.push_back(f1); 
    execute(x); 
} 
+0

Q1 Это решает одну проблему передачи аргумента. Но, я просто не хочу нажимать обычную функцию в векторе, я хочу также нажимать функтор и функцию лямбда. Поэтому я не могу использовать тип decltype для получения типа. Как это исправить? – DKR

+0

См. Ответ @ songyuanyao о том, как вы можете достичь этого с помощью шаблонов. Пример: http://coliru.stacked-crooked.com/a/df682223032a9ec9 –

+0

Или вы хотели написать шаблоны «без»? – DKR

Смежные вопросы