【发布时间】:2021-08-31 13:14:37
【问题描述】:
我有一些函数来支持它们都采用同质参数。但是每个函数可以采用不同的数量。 这些函数通过指定函数名及其参数来调用。
例子,
#include <iostream>
#include <vector>
#include <cmath>
enum class operation{
abs,
add,
ceil,
floor,
sub
};
template <typename... T>
int foo(operation op, const T&... args){
std::vector<int> operands({args...});
switch(op){
case operation::abs:
return abs(operands[0]);
case operation::add:
return operands[0] + operands[1];
case operation::ceil:
return ceil(operands[0]);
case operation::floor:
return floor(operands[0]);
case operation::sub:
return operands[0] - operands[1];
}
}
int main() {
// operation is a user input at runtime
operation op = operation::add;
// call foo with some arguments
std::cout << foo(op, 5, 6);
return 0;
}
这有一定的问题:
- 使用向量,因此存在不必要的堆分配。
- 代码膨胀,因为所有操作都是针对不同数量的参数编译的。
- 一个非常大的 if/else,因为我不断添加操作。
大多数相关问题都使用函数对象和模板来解决这个问题。但是这里的操作是未知的编译时间常数。
有没有更好的方法来做到这一点,而不必为 foo 的所有实例中的所有操作编译代码?
【问题讨论】:
-
如何直到运行时才知道操作,但在编译时知道操作的参数?
-
1和2可以通过不使用单个可变参数函数来解决,而是每个参数一个函数:foo(op, arg)处理单参数运算符,foo(op, arg1, arg2)处理两个-参数的。3可以通过维护从operation值到函数指针的映射来解决(可能再次单独映射每个参数)。
标签: c++ c++14 metaprogramming variadic-templates variadic-functions