Почему std :: function не может принять выведенный тип в качестве параметра шаблона?

#include <functional>

using namespace std;

template<class CharType>
void f1(CharType* str, function<bool(CharType)> fn_filter)
{}

template<class CharType>
void f2(CharType* str, function<bool(char)> fn_filter)
{}

void f3(char* str, char c)
{
auto fn_filter = [=](char e) -> bool
{
return e == c;
};

f1(str, fn_filter); // error C2784
f2(str, fn_filter); // OK
}

int main()
{
f3("ok", 'k');
}

// error C2784: 'void f1(CharType *,std::function<bool(CharType)>)'
// : could not deduce template argument for 'std::function<bool(CharType)>'
// from 'f2::<lambda_36be5ecc63077ff97cf3d16d1d5001cb>'

Мой компилятор VC ++ 2013.

Почему f1 не работает, как ожидалось?

4

Решение

Проблема для компилятора состоит в том, чтобы решить, какой из ваших параметров использовать для вывода типа. Если вы помогаете компиляции, нарушая возможный вывод из второго параметра и сила это использовать первый, он работает как положено:

template<typename T> struct identity { using type = T; };

template<class CharType>
void f1(CharType* str, typename identity<function<bool(CharType)>>::type fn_filter)
{}

Живой пример

4

Другие решения

Лямбда не имеет типа std::function<bool(char)>это просто вызываемый объект с реализацией определенного типа.

Может быть переоборудованный в std::function<bool(char)>, но это не помогает компилятору определить тип для случая шаблона. Там может быть, например, много возможностей для CharType для которого лямбда может быть преобразована в std::function<bool(CharType)>,

Компилятор пытается сопоставить тип лямбды с параметром функции шаблона. Лямбда имеет, например, такой тип lambda_t_1234 и параметр шаблона std::function<bool(CharType)>, Типы не связаны, и не ясно, что CharType должен быть здесь.

Это также не является особенным для лямбд или std::function<>, То же самое происходит во всех таких случаях:

template<typename Char>
void f(const std::basic_string<Char> &str) {
}

Если вы попытаетесь вызвать эту функцию шаблона с char* Параметр не будет работать, потому что связь с параметром шаблона не ясна.

8

По вопросам рекламы [email protected]