使用lambda表达式隐式模板推导

时间:2014-05-04 13:41:46

标签: templates c++11 lambda

我尝试在XCode 5.1上使用c ++ 11构建以下代码:

template<class T>
float calc2(std::function<float(T)> f) { return -1.0f * f(3.3f) + 666.0f; }

int main(int argc, const char* argv[])
{
    calc2([](float arg) -> float{ return arg * 0.5f; }); //(1) - Will not compile - no matching function...
    calc2<float>([](float arg) -> float{ return arg * 0.5f; }); // (2) - Compiles well
    return 0;
}

有人可以解释为什么(1)不编译?编译器不应该从lambda定义中推导出T?

谢谢!

1 个答案:

答案 0 :(得分:1)

有时没有什么是正确的做法。 C ++类型系统将为您做脏事:

template<class F>
float calc2(F f)
{
  return -1.0f * f(3.3f) + 666.0f;
}

如果你传递任何会使函数无效的东西,它自然会无法编译。

缺点是如果你传递任何使函数无效的东西,它就会编译,即使它没有意义。如果您想要更具选择性,可以使用static_assert

#include <type_traits>

template<class F>
float calc2(F f)
{
  static_assert(std::is_same<float, decltype(f(std::declval<float>()))>::value,
                "The argument must return float when called with float arg!");

  return -1.0f * f(3.3f) + 666.0f;
}