2013-04-09 3 views
0

Я использую повышение :: функции, как это:повышение :: связать неявное преобразование для повышения :: функция или указатель на функцию

template<class T1> 
void run(boost::function<void (T1)> func, string arg) 
{ 
    T1 p1 = parse<T1>(arg); 
    func(p1); 
} 

При использовании, как это, все в порядке:

void test1(int i) 
{ 
    cout << "test1 i=" << i << endl; 
} 

... 

boost::function<void (int)> f = &test1; 
run(f, "42"); 

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

template<class T1> 
void run(void (*func)(T1), string arg) 
{ 
    T1 p1 = parse<T1>(arg); 
    (*func)(p1); 
} 

... 

run(&test1, "42"); // this is OK now 

Теперь я хочу быть в состоянии передать результат boost :: bind для функции run(). Как это:

void test2(int i, string s) 
{ 
    cout << "test2 i=" << i << " s=" << s << endl; 
} 

... 

run(boost::bind(&test2, _1, "test"), "42"); // Edit: Added missing parameter 42 

Но это обыкновение компиляции: Под редакцией

bind.cpp: In function ‘int main()’: 
bind.cpp:33:59: error: no matching function for call to ‘run(boost::_bi::bind_t<void, void (*)(int, std::basic_string<char>), boost::_bi::list2<boost::arg<1>, boost::_bi::value<std::basic_string<char> > > >, std::string)’ 
bind.cpp:33:59: note: candidates are: 
bind.cpp:7:6: note: template<class T1> void run(boost::function<void(T1)>, std::string) 
bind.cpp:14:6: note: template<class T1> void run(void (*)(T1), std::string) 

Как я должен перегружать работать(), чтобы принять повышение :: Bind()?

Edit 2

Я знаю, что могу сделать это так:

boost::function<void (int)> f = boost::bind(&test2, _1, string("test")); 
run(f, "42"); 

Но я хотел бы использование менее многословным.

Редактировать 3

Измененного пробега() прототип от run(boost::function<void (T1)>, T1) до run(boost::function<void (T1)>, string) разработать фактический случай использования. Ссылка ответ Игорь Романович в

Исходный файл всего может быть получен here

+0

Нет такой вещи, как «неявный бросок». Бросок - это то, что вы пишете в исходном коде, чтобы сообщить компилятору сделать преобразование. Есть преобразования, которые компилятор может сделать без броска; такое преобразование является «неявным преобразованием». Когда вы используете бросок, это «явное преобразование». –

+0

Действительно. Название вопроса должно быть изменено. – anorm

ответ

1

Ни function, ни тип результата bind могут быть конвертированы в указатель на функцию, так что вы не можете передать их run функции с ее током подпись.

Однако, вы можете изменить run подпись, чтобы позволить ему принимать любые вызываемая:

template<class F, class A1> 
void run(F f, A1 arg) 
{ 
    f(arg); 
} 

Теперь вы можете передать функцию указателя, связующее вещество, boost::function или что когда-либо вызываемая вы хотите - до тех пор, так как он ожидает 1 аргумент. (Обратите внимание, однако, что с этой тривиальной сигнатурой run не будет forward аргументов f.)

+0

Да, решает проблему, описанную мной (+1). Однако фактическая функция run() должна знать тип аргумента, и аргумент не является частью функции реального мира. – anorm

+0

Функция реального мира использует тип аргумента, чтобы вызвать шаблонный синтаксический анализатор строк, чтобы я мог вызывать функцию, давая ей строковые аргументы, а функция run() анализирует аргументы как правильные типы и вызывает функцию – anorm

+0

Я редактировал вопрос чтобы отразить это требование. – anorm