c++ - 为什么 std::is_function 对简单函数和 lambda 返回 false?

标签 c++ c++11 lambda template-meta-programming typetraits

有如下一段代码:

#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 模板参数时,它会正常编译和运行。为什么?

最佳答案

来自 cppreference :

Checks whether T is a function type. Types like std::function, lambdas, classes with overloaded operator() and pointers to functions don't count as function types.

This answer说明您还需要使用 std::remove_pointer<F>::type作为类型,因为函数在按值传递时被转换为指向函数的指针。所以你的代码应该是这样的:

template <typename F,
          typename = typename std::enable_if<
                                              std::is_function<
                                                typename std::remove_pointer<F>::type
                                              >::value
                                            >::type>
int fun( F f )
{
  return f(3);
}

关于c++ - 为什么 std::is_function 对简单函数和 lambda 返回 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37946727/

相关文章:

c++ - 是否有任何关于从 C 迁移到 C++ 的指南

c++ - SIP4 中的共享指针和构建(原为 : Dynamic casting in SWIG/python? )

c++ - 是否可以使用默认泛型参数在 C++ 中定义 lambda?

c# - DbContext "using"在一行中

c# - 在 C# 中使用扩展方法与 lambda 表达式

c++ - 修复 lib 兼容性 c++ mingw 和 postgresql

c++ - 开发 Cpp "make.exe"错误代码 = 0xc00000fd

c++ - 使用 cmake 将 libconfig 与 C++ 链接时出错?

C++ 11 - 当我将局部变量作为参数传递给线程时是否安全

c++ - 寻找QMenu真实位置