2015-10-13 3 views
0

Я пытаюсь передать функцию обратного вызова в качестве параметра функции. Но получение ошибок с заменой шаблонов в следующем коде. Не знаю, почему замена шаблона не работает.Ошибка замены шаблона с помощью std :: function

#include<iostream> 
#include <map> 
#include <tuple> 
#include <functional> 

template<typename A,typename B> 
void myfun(std::map<A,B> & mm, std::function<std::tuple<A,B>(void)> fn) 
{ 
    A key; 
    B val; 
    std::tie(key,val) = fn(); 
    mm[key] = val; 
} 

std::tuple<std::string,int> fun() 
{ 
    return std::make_tuple(std::string("hi"),1); 
} 

int main() 
{ 
    std::map<std::string,int> gg; 
#if 0 
     //fixed version 
     std::function<std::tuple<std::string,int>(void)> yy = fun;//fixed 
     myfun(gg,yy);//fixed 
#else 
     // error causing code 
     myfun(gg,fun); 
#endif 
} 

И ошибка заключается в следующем

main.cpp:8:6: note: template argument deduction/substitution failed: 

main.cpp:25:17: note: mismatched types 'std::function<std::tuple<_T1, _T2>()>' and 'std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> (*)()' 

    myfun(gg,fun); 
+0

' "привет"' может быть выведено 'сопзЬ символ *', попробуйте использовать 'зЬй :: строка ("привет")' ' – EGOrecords

+1

станд :: function' и обычные функции - это разные вещи, см. http://stackoverflow.com/questions/9054774/difference-between-stdfunction-and-a-standard-function-pointer. – Petr

+0

@JohannesWalcher или намного приятнее '' hi 's' с C++ 14 – CoffeeandCode

ответ

3

компилятор не может и приведение к std::function и вывести аргументы шаблона. Он не понимает отображение между произвольным указателем функции и std::function.

Существует несколько способов обойти это.

Вы можете явно создать std::function на месте вызова:

myfun(gg,std::function<std::tuple<std::string,int>(void)>{fun});` 

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

myfun(gg,make_function(fun)); 

Вы можете просто забыть о std::function и вывести весь тип функции. Это подход, который я бы:

template<typename A,typename B, typename Fun> 
void myfun(std::map<A,B> & mm, Fun fn) 
{ 
    A key; 
    B val; 
    std::tie(key,val) = fn(); 
    mm[key] = val; 
} 
Смежные вопросы