从模板中的子表达式中提取类型

时间:2017-11-14 22:38:55

标签: c++ templates

给出以下模板化函数:

template <typename T>
void f(std::function <void (T)>) {}

在调用f?

时,我是否可以在不必明确提及的情况下提取T.

f<int>([](int){});工作正常,但我希望推断T和f([](int){});才能正常工作。后者错误地说“没有匹配的呼叫功能”。

1 个答案:

答案 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等算法的可调用对象中提取参数类型来回避这样的问题。它只接受任意可调用类型,然后尝试调用它。