Вывод типа C++11 с помощью функции lambda и std ::

У меня есть следующий фрагмент кода, который, хотя и совершенно тривиален, иллюстрирует шаблон, который я пытаюсь использовать в более общем коде.

template<typename InT, typename ResT>
ResT unary_apply( InT val, std::function<ResT(InT)> fn )
{
    return fn(val);
}

Я хотел бы иметь возможность вызывать унарные _apply с указателями функций, функторами, лямбда-выражениями и т. д. :, поэтому использование std::functionпозволяет абстрагироваться от всего этого.

Когда я пытаюсь использовать вышеизложенное следующим образом, C++ (g++ 4.7 )не может выполнить вывод соответствующего типа:

double blah = unary_apply( 2, []( int v ) { return 3.0 * v; } );

Ошибка с

src/fun.cpp:147:75: error: no matching function for call to ‘unary_apply(int, test()::<lambda(int)>)’
src/fun.cpp:147:75: note: candidate is:
src/fun.cpp:137:6: note: template<class InT, class ResT> ResT unary_apply(InT, std::function<ResT(InT)>)
src/fun.cpp:137:6: note:   template argument deduction/substitution failed:
src/fun.cpp:147:75: note:   ‘test()::<lambda(int)>’ is not derived from ‘std::function<ResT(double)>’

И я обнаружил, что на практике мне приходится явно указывать параметры шаблона (, я считаю, что это просто тип возвращаемого значения, который невозможно вывести):

double blah = unary_apply<int, double>( 2, []( int v ) { return 3.0 * v; } );

Я не настолько хорошо знаком с правилами вывода типов в C++11,но вышеприведенное поведение кажется разумным (Я вижу, что вывод с помощью внутренней механики std::function, вероятно, является довольно сложной задачей ). Мой вопрос: :возможно ли повторно -написать функцию unary_applyвыше, чтобы сохранить ту же гибкость (с точки зрения типов функций/функторов и т. д., которые могут быть переданы в качестве второго параметра )а также дает больше подсказки для вывода типа, поэтому мне не нужно явно указывать параметры шаблона в точке вызова?

8
задан Alex Wilson 5 July 2012 в 12:10
поделиться