给出以下模板化函数:
template <typename T>
void f(std::function <void (T)>) {}
在调用f?
时,我是否可以在不必明确提及的情况下提取T. f<int>([](int){});
工作正常,但我希望推断T和f([](int){});
才能正常工作。后者错误地说“没有匹配的呼叫功能”。
答案 0 :(得分:2)
如果传递给函数的对象实际上具有类型T
,则可以推导出std::function<void(T)>
。如果你传入的类型是lambda,那么你必须从lambda的函数调用操作符的类型推导出它,如下所示:
template <class Callable, class Arg, class T>
void f_helper(Callable callable, Ret (Callable::*)(T)) {
// do something with T
}
template <class Callable>
void f(Callable callable) {
f_helper(callable, &callable::operator());
}
实际上,实际上它比这更烦人,因为根据lambda是否被声明为可变(确定f_helper
是否为{{} operator()
,你需要至少两次重载const
。 1}}),在C ++ 17中,你还需要根据lambda是noexcept
再次加倍重载次数。
标准库通过不尝试从传递给std::sort
等算法的可调用对象中提取参数类型来回避这样的问题。它只接受任意可调用类型,然后尝试调用它。