c++ - 从作为模板函数参数传递的 std::function 推断返回和参数类型?

标签 c++ templates std-function

我已经四处寻找了一段时间,但找不到我正在寻找的答案 - this question这可能是最接近我的想法的。

一句话:是否可以声明一个接受 std::function 参数的模板函数,并推导出函数的返回类型和参数类型的模板参数?示例:

//this works to pass the std::function in
template<class T>
void doSomething(std::function<T> f) {
    f();
}

//this is more what i am looking for - can R and P be deduced automatically - does not work!
template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
    f();
}

这是因为函数签名或函数类型本身被认为是一件事,因此不能“分解”?我意识到有 decltypestd::result_of 但无法想象我如何在这里使用它们。

作为补充一点,我如何使用可变参数模板扩展第二个示例以具有多个参数和推导?

最佳答案

template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
    f(P{});
}

可以,但只有当你通过 std::function 时它才有效到该函数,并且该函数有一个非 void 参数。但这是一种限制。您可以使用

template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
    f(std::forward<Args>(args)...);
}

这将需要任何 std::function以及它的参数并调用它们,就像您在调用站点中所做的那样。但这仍然是有限的,因为调用站点要求您使用 std::function所以你不能向它传递任何可隐式转换为 std::function 的内容。

使用 C++17 和 class template argument deduction (CTAD) 但这不再是问题了。我们可以创建一个采用任何类型的重载,然后使用 CTAD 构造一个 std::function 来为我们填充类型。这看起来像

template<class Func, class... Args>
void doSomethingElse(Func&& f, Args&&... args) {
    doSomethingElse(std::function{std::forward<Func>(f)}, std::forward<Args>(args)...);
}

template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
    f(std::forward<Args>(args)...);
}

现在除了std::function之外的任何东西将转到void doSomethingElse(Func&& f, Args&&... args) ,转换为 std::function ,并传递给 void doSomethingElse(std::function<R(Args...)> f, Args&&... args)因此您可以在其中使用返回类型和参数类型。

关于c++ - 从作为模板函数参数传递的 std::function 推断返回和参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520170/

相关文章:

c++ - 为什么我的 C++/Win32 项目无法在 Visual Studio 之外工作?

c++ - 如何使用另一个类作为类模板特化

c++ - 非类型模板参数可以是 "void*"类型吗?

c++ - 返回具有自动返回类型的 std::function

c++ - 迭代器模式 - 错误 C2679 : binary '<<' : no operator found which takes a right-hand operand of type 'std::string'

c++ - C 代码在 Windows 中编译,在 Linux 上给出编译错误

c++ - std::function、Clang 6.0 和 MSVC (10.0017134.12) - 可能的 ABI 错误或所需的编译器标志

c++ - 使用 std::function 作为类成员创建回调

c++ - 类似于 Turbo C++ 的编辑器

codeigniter - 哪个 CMS 会更好地在 CI 的不同页面中加载不同的模板?