我尝试在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?
谢谢!
答案 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;
}