c++ - 模板函数的包装器

标签 c++ templates metaprogramming

我想要完成的是以下内容:

// or any templated function
template <typename... Args>
void function(Args... args) {}

// wrapper
void launch(???) { ??? }

int main()
{
    // first option
    launch(function, 1, 2, 3, 4);
    // second option
    launch<function>(1, 2, 3, 4);
}

据我所知,第一个选项是不可能的,因为我必须传递专门的模板函数(我试图避免)。

对于第二个选项,我不知道是否可行,我想出了以下不工作实现:

template <template <typename...> class Function, typename... Args>
void launch(Args... args)
{
    Function<Args...>(args...);
}

这最终给了我:

main.cpp:18:5: error: no matching function for call to 'launch'
    launch<function>(1, 2, 3, 4);
    ^~~~~~~~~~~~~~~~
main.cpp:9:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Function'
void launch(Args... args)
     ^
1 error generated.

那么,这样的事情有可能吗?

最佳答案

除了调用它们(并让参数被推导)或实例化它们(通过手动指定模板参数)之外,您基本上不能对函数模板做任何事情。

我相信还有一些利基情况,其中可以推导模板参数并在没有实际调用的情况下选择特定的实例化,但它们在这里无济于事 AMA 的回答展示了如何做到这一点!

通用 lambda 可能会也可能不会帮助您解决问题,但您需要为每个函数模板提供一个这样的转发 lambda,使其“可通过”:

#include <functional>

// or any templated function
template <typename Arg1, typename Arg2>
void function(Arg1 arg1, Arg2 arg2) {}

int main()
{
    auto wrapper = [](auto arg1, auto arg2) {
        return function(arg1, arg2);
    };

    std::invoke(wrapper, 1, 2);
}

Demo

(使用可变 lambda 完美转发到可变函数会更复杂。)

所以你不妨一开始就以仿函数结构的形式编写函数模板,或者以从非模板函数返回的 lambdas 的形式编写函数模板。

关于c++ - 模板函数的包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56273287/

相关文章:

c++ - 由于 giflib 更新,从源代码编译 Gnash 失败 - 替代方案?

c++ - Lua C API 嵌套表段。过错

c++ - 我们是否需要在嵌套类型的成员参数前加上 "::"前缀?

Java 反射与代码生成

c++ - 在 Linux 上使用 Qt 的限定名无效

c++ - 不重载所有运算符的 int 包装器

c++ - 模板重载和 SFINAE 仅适用于函数而不适用于类

C++在函数模板中传递函数指针

ruby-on-rails - 带有嵌套模块的 Object.const_set 中的常量名称错误

ruby-on-rails - ruby respond_to_missing?叫 super 还是不叫?