C++模板参数包展开时函数调用为何按反向顺序执行?
问题原因
你对模板展开后的参数顺序判断是正确的,问题的核心是C++不同版本对函数参数求值顺序的规定差异:
- C17之前(包括你使用的C11标准),没有规定普通函数的参数求值顺序,编译器可以自主选择从左到右或者从右到左求值。你所用的编译器默认采用了从右到左的参数求值策略,所以作为最后一个参数的
call_and_return_0(f, 19)会最先执行,最终输出顺序就是19到0。 - 你参考的C17版本代码要么使用了C17新增的逗号折叠表达式(折叠表达式的逗号运算符严格遵循从左到右求值顺序),要么受益于C++17新增的函数参数从左到右求值规定,所以迭代顺序固定为0到19。
C++11兼容修复方案
不需要修改integer_sequence相关实现,只要把loop函数里的variadic_noop调用替换为数组初始化列表即可,C++标准明确规定大括号初始化的元素求值顺序严格从左到右,不受编译器实现影响:
template<class T, T... Is, class F> void loop(integer_sequence<T, Is...>, F&& f) { // 数组初始化列表保证严格从左到右执行 int unused[] = { (call_and_return_0(f, Is), 0)... }; (void)unused; // 消除未使用变量的编译警告 }
内容的提问来源于stack exchange,提问作者itzjackyscode
相关产品推荐
相关产品推荐

