使用variadic函数作为模板参数

sig*_*lor 0 c++ templates variadic-functions variadic-templates

我想在不改变Child1Child2类的情况下使以下代码工作:

#include <iostream>

int triple(int a) {
    return a * 3;
}

int add(int a, int b) {
    return a + b;
}

template<int (*F)(int)>
class Parent {
    public:
        Parent(int a) {
            std::cout << "constructed: " << F(a) << std::endl;
        }
};

class Child1 : Parent<triple> {
    public:
        Child1(int a) : Parent(a) {}
};

/*class Child2 : Parent<add> {
    public:
        Child2(int a, int b) : Parent(a, b) {}
};*/

int main() {
    Child1 child(4);
    //Child2 child(5, 6);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的那样,Child1继承Parent自已使用该triple函数实例化的内容.因此,当Child1用四实例化时,它输出" constructed: 12".

相比之下,Child2被评论出来,因为它显然还不起作用.在main函数中,我试图将两个参数传递给Child2构造函数,就像底层add()函数所期望的那样.然而,Parent构造函数只接受一个参数,可能需要template<typename Args...>在它前面才能得到解决方案.另外,Parent该类需要一个模板参数int (*F)(Args...).最终,构造Child2像main函数一样的实例应该输出" constructed: 11".

我怎样才能实现这一点,即创建一个模板参数,该参数是一个可以包含任意数量参数的函数?同样,请注意,Parent类的代码是唯一可以更改的代码.

use*_*670 5

使用C++ 17您可以使用推导出的非类型模板参数,并使构造函数成为可变参数模板:

template<auto x_pointer_to_function>
class Parent
{
    public:
    template<typename... x_Args>
    Parent(x_Args &&... args)
    {
        std::cout << "constructed: " << ((*x_pointer_to_function)(::std::forward<x_Args>(args)...)) << std::endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

在线编译器