【发布时间】:2018-10-09 13:02:37
【问题描述】:
我想编写一个函数来比较几个值并检查其中哪个是最小的。我想将其实现为可变参数函数模板。我知道自 C++11 以来就有一个用于此目的的功能,但由于某些原因,我目前无法使用它。所以我尝试使用<cstdarg> 库,但偶然发现了一些问题。由于某种原因,当我将函数用作模板时,参数的偏移量计算错误。如果我使用固定类型显式实现该功能,我没有问题。
我的代码:
#include <cstdarg>
#include <iostream>
#include <limits>
template <typename T>
T smallestOf(const int count, const T val1, ... ) { /* I use val1 to determine the template type */
va_list args;
va_start(args, val1);
T smallestVal = std::numeric_limits<T>::max();
for(int i = 0; i < count; i++) {
T nextVal = va_arg(args, T);
std::cout << "nextVal: " << nextVal << std::endl;
if(nextVal < smallestVal) smallestVal = nextVal;
}
va_end(args);
return smallestVal;
}
int main() {
std::cout << "Smallest value: " << smallestOf(3, 10, 20, 30) << std::endl;
}
产生以下输出:
nextVal: 20
nextVal: 30
nextVal: 4217000
Smallest value: 20
看起来函数读取了它的内存,因为偏移量是错误的。这是为什么呢?
【问题讨论】:
-
可变参数函数实际上是 C 的遗留物,并且对 C++ 的支持很差。例如,只有第二个参数
val1的类型为T,其他参数的类型不检查,可以是anything。尝试改用template parameter packs。 -
无论是模板or not都会产生错误的输出
-
另外,这个特定的函数可以实现为
constexpr函数,该函数(可能)在编译时进行评估。
标签: c++ templates variadic-templates variadic