gpt4 book ai didi

C++11 可变参数模板在类中调用函数

转载 作者:行者123 更新时间:2023-12-01 14:20:14 25 4
gpt4 key购买 nike

我正在学习 C++11 中的可变参数模板。如何调用 test.finder 作为 test.var_finder 的函数参数?

#include <functional>
#include <iostream>

class c_test {
public:

double finder(double a, double b = 0) {
return a + b;
};


template<typename... Args>
double var_finder(double c, Args... args, std::function<double (Args... args)> func) {
return c * func(args...);
};
};

int main () {
c_test test;

std::cout << test.var_finder(0.1, 2, test.finder) << std::endl;

return 0;
}

我的预期结果是 0.1 * (2 + 0) = 0.2。

最佳答案

我猜你有点把可变参数模板部分和一些设计缺陷混在一起了

让我们开始吧。

序言:处理可变模板的正确方法是使用rvalue-referencestd::forward来实现 perfect forwarding .

1) 简单的方法:你根本不需要上课

您实际上并没有指代任何成员,因此类只会带来复杂性。这些情况最好引用一个免费的功能

#include <functional>
#include <iostream>

double finder(double a, double b = 0) {
return a + b;
};

template<typename Func, typename... Args>
double var_finder(double c, Func&& f, Args&&... args) {
return c * std::forward<Func>(f)(std::forward<Args>(args)...);
};

int main () {
std::cout << var_finder(0.1, finder, 2, 0) << std::endl;

return 0;
}

Demo 1

您的函数接受 2 个参数,因此您必须将零作为第二个参数传递。

2) 使用类

您尝试的问题是您想使用 c_test 本身的函数调用 c_test.var_finder。现在你必须弄清楚你想要什么样的设计。你可以做出2个假设。首先是“我无论如何都想要我的类中的查找器函数”,然后你必须将它设为 static 因为它真的不使用类成员所以你不需要 c_test< 的实例,对吧?所以使用自由函数或静态成员函数会留下 var_finder 实现,你只需要这样调用它

#include <functional>
#include <iostream>

class c_test {
public:
static double finder(double a, double b = 0) {
return a + b;
};


template<typename Func, typename... Args>
double var_finder(double c, Func&& f, Args&&... args) {
return c * std::forward<Func>(f)(std::forward<Args>(args)...);
};
};

int main () {
c_test test;

std::cout << test.var_finder(0.1, &c_test::finder, 2, 0) << std::endl;

return 0;
}

Demo 2

您可以做的第二个假设是“不,我希望使用 var_finder 调用任何函数成员,无论它来自哪里”。我强烈反对这种方法,因为它是从糟糕的设计中提取解决方案,因此我建议重新考虑您的设计以落入解决方案 1 或 2。

3) 奖励:一个不错的设计

您可以添加一个非可变参数函数并将用法委托(delegate)给 lambda 的使用,这允许您在其中使用成员函数而无需定义可变参数模板来处理它(这是标准库函数)。

#include <functional>
#include <iostream>

double finder(double a, double b = 0) {
return a + b;
};

template<typename Func, typename... Args>
double var_finder(double c, Func&& f, Args&&... args) {
return c * std::forward<Func>(f)(std::forward<Args>(args)...);
};

template<typename Func, typename... Args>
double var_finder(double c, Func&& f) {
return c * std::forward<Func>(f)();
};

class c_test
{
public:
double finder(double a, double b = 0) {
return a + b;
};
};

int main () {
double a = 2.0;
double b = 0.0;

// use as usual
std::cout << var_finder(0.1, finder, a, b) << std::endl;

// use with lambda
std::cout << var_finder(0.1, [a,b](){ return a+b; }) << std::endl;

// lambda with member argument, less gruesome than a variadic template calling a member function
c_test c;
std::cout << var_finder(0.1, [a,b, &c](){ return c.finder(a,b); }) << std::endl;

return 0;
}

Bonus Demo

关于C++11 可变参数模板在类中调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62211078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com