Имея следующий фрагмент кода:Почему std :: is_function возвращает false для простых функций и лямбда?
#include <iostream>
#include <type_traits>
template <typename F,
typename = typename std::enable_if<
std::is_function<F>::value
>::type>
int fun(F f) // line 8
{
return f(3);
}
int l7(int x)
{
return x%7;
}
int main()
{
auto l = [](int x) -> int{
return x%7;
};
fun(l); // line 23
//fun(l7); this will also fail even though l7 is a regular function
std::cout << std::is_function<decltype(l7)>::value ; // prints 1
}
Я получаю следующее сообщение об ошибке:
main2.cpp: In function ‘int main()’:
main2.cpp:23:8: error: no matching function for call to ‘fun(main()::<lambda(int)>&)’
fun(l);
^
main2.cpp:8:5: note: candidate: template<class F, class> int fun(F)
int fun(F f)
^
main2.cpp:8:5: note: template argument deduction/substitution failed:
main2.cpp:5:11: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
typename = typename std::enable_if<
^
Когда я закомментировать параметр std::enable_if
шаблона, то он компилирует и работает просто отлично. Зачем?
'std :: is_function' проверяет только типы функций, которые не включают лямбда. Есть ли причина, по которой вам нужно использовать SFINAE? Если вы действительно хотите сделать чек, вы можете проверить, что 'f (3)' правильно сформирован, а не проверяет, является ли функция 'f' функцией- – TartanLlama
Похоже, вы действительно ищете что-то вроде' 'std :: is_callable'] (http://en.cppreference.com/w/cpp/types/is_callable), который доступен с C++ 17, но «может быть реализован в терминах« std :: is_convertible »и' std :: result_of' "с чистым C++ 11. – m8mble
@TartanLlama Как бы вы проверили, правильно ли сформирован 'f (3)'? – Patryk