可变参数模板编译报错:表达式列表被视为复合表达式问题
解决C++14中函数参数包传递的编译错误:expression list treated as compound expression
我来帮你分析并解决这个问题,你的核心错误有两个,先拆解最直接的编译问题:
错误根源解析
你的measure_time模板函数定义里,第一个参数只写了类型func却没有变量名,当你在函数内部写func(&args...)时,编译器会把func当成模板参数的类型名,而不是你传入的函数指针/对象。这时候它会尝试把&args...这个表达式列表做「函数式类型转换」,试图转成func类型,这就触发了那个编译错误。
另外,&args...的写法本身也不符合你的需求:你的binary_search函数需要的是int*, int, int, int类型的参数,而如果传入的args已经是int*, int, int, int,给每个参数加&会把第一个参数变成int**,和函数要求的类型不匹配——这也是为什么加-fpermissive能编译但其实隐藏了类型不匹配的问题,运行时可能会出bug。
修复后的代码
先把measure_time函数修正过来:
#include <chrono> #include <iostream> // 给模板参数第一个参数加变量名,并且正确调用函数 template<typename Func, typename ...Types> void measure_time(Func f, Types... args) { auto start = std::chrono::system_clock::now(); f(args...); // 直接调用传入的函数对象/指针,传递参数包 auto end = std::chrono::system_clock::now(); std::cout << "Time for execution " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << " microseconds\n"; }
你的binary_search函数可以保留,这里顺便修正一个逻辑小bug:
int binary_search(int *a, int v, int l, int r) { while (r >= l) { // 原代码的r>=1是逻辑错误,改成r>=l才符合二分搜索的范围判断 int m = (l + r) / 2; if (v == a[m]) return m; if (v < a[m]) r = m - 1; else l = m + 1; } return -1; }
调用示例如下:
int main() { int test_arr[] = {1, 3, 5, 7, 9, 11}; int target = 7; // 直接传递参数,arr会自动退化为int*,和函数参数匹配 measure_time(binary_search, test_arr, target, 0, sizeof(test_arr)/sizeof(test_arr[0]) - 1); return 0; }
额外说明
- 模板参数名我改成了
Func(首字母大写),这是C++的惯例,用来区分类型名和变量名,避免混淆。 - 如果你的某些函数确实需要传递参数的地址,不要在包装函数里统一加
&,而是在调用measure_time的时候传入地址即可——这样包装函数更通用,能适配不同参数类型的函数。
内容的提问来源于stack exchange,提问作者Juri
相关产品推荐
相关产品推荐

