C++处理参数包时何时需要省略号?sizeof...使用规则相关疑问
关于C++参数包中
sizeof与sizeof...的用法差异解答 核心结论
- 获取参数包的元素数量,必须使用
sizeof...运算符,这是C++标准的明确规定。
二者本质差异
sizeof运算符的作用是计算单个类型/对象占用的内存字节数,而sizeof...是专门为参数包设计的运算符,作用是获取参数包中包含的元素个数,二者的语义完全不同。
「不加省略号能编译但出现多余尾逗号」的原因
你代码中的逗号折叠表达式((os << tupleArgs << (++n != 判断条件 ? ", " : "")), ...),会把<<后面整个括号内的内容当作展开模式的一部分。如果你写的是sizeof(Ts)而非sizeof...(Ts),那么sizeof(Ts)会被当作参数包展开的一部分,每次迭代对应当前参数包位置的类型的sizeof值,而非整个参数包的总个数。
举个实际例子:如果你传入的是std::tuple<int, int, int>,sizeof...(Ts)的值是固定的3,每次比较的是递增的n和3,到第三次迭代时n=3和3相等,就不会输出逗号,不会出现尾逗号。而如果写成sizeof(Ts),每次展开得到的都是sizeof(int)也就是4,三次迭代的判断分别是1!=4、2!=4、3!=4,结果都为真,三次都会输出逗号,自然就出现了多余的尾逗号。
参数包的省略号使用规则
- 声明参数包时:省略号放在参数类型/模板参数名前,用于标识这是一个参数包,比如
template<typename... Ts>(模板类型参数包)、void func(Ts... args)(函数参数包)。 - 展开参数包时:省略号放在需要展开的模式之后,会把模式按参数包的元素依次展开,比如
(std::cout << args, ...)就是把每个args依次传给cout输出,用逗号运算符折叠。 - 获取参数包元素个数时:必须使用
sizeof...(参数包名),这里的省略号是运算符的固定组成部分,不属于展开操作,返回值是编译期常量,代表参数包的总元素数。
内容的提问来源于stack exchange,提问作者jwezorek
相关产品推荐
相关产品推荐

