C++可变参数模板中的省略号

看可变参数模板代码时常会遇到省略号的使用,这类奇特的"..."出现位置还不固定,容易引起困惑。C++最近一直不用都快废了,在此想对省略号的使用做个简单归纳以提醒自己。可变参数模板以两种方式使用省略号。 在参数名称的左侧,表示"参数包",在参数名称的右侧,意为将参数包逐项展开。

参数包声明

一般在可变参数类模板可变参数函数模板的定义时,会在参数名称的左边添加省略号以表示"参数包":

cpp 复制代码
template<typename... Arguments> class vtclass;

vtclass< > vtinstance1;
vtclass<int> vtinstance2;
vtclass<float, bool> vtinstance3;
vtclass<long, std::vector<int>, std::string> vtinstance4;
cpp 复制代码
template <typename... Arguments> returntype functionname(const Arguments&... args);
template <typename... Arguments> returntype functionname(Arguments&... args);
template <typename... Arguments> returntype functionname(Arguments&&... args);
template <typename... Arguments> returntype functionname(Arguments*... args);

当然,类模板和函数模板也可以限定一个以上参数的情形,限定多个参数以此类推不赘述:

cpp 复制代码
template <typename First, typename... Rest> class classname;
cpp 复制代码
template <typename First, typename... Rest> returntype functionname(const First& first, const Rest&... args);
参数包展开

一般在函数参数声明 或者函数调用时,在参数名称的右边添加省略号,表示将参数包逐项展开:

cpp 复制代码
// v1 is NOT a function parameter pack:
template <typename... Types> void func1(std::vector<Types...> v1);

// v2 IS a function parameter pack:
template <typename... Types> void func2(std::vector<Types>... v2);

vector<int> v1, v2, v3;
func1(v1, v2, v3);//compile err
func2(v1, v2, v3);//compile ok

这里注意省略号的位置,虽然我们本意都是想展开参数包Types,但实际code的意图到底是vector<Types>里面的Types参数有多个,还是有多个vector<Types>?显然应该是后者,因为不存在template<class T...> class vector这样的形式,只有标准库中的template<class T> class vector。因此前者编译错误。

函数调用也在参数名(实参)后面添加省略号以将实参展开:

cpp 复制代码
template <typename First, typename... Rest> void print(const First& first, const Rest&... rest) {
    cout << first << ", ";
    print(rest...); // recursive call using pack expansion syntax
}

template<class...Args>
void Emplace(Args&&... args) {
	Destory();
	Create(forward<Args>(args)...);
}

这里同样forward的省略号在整个forward<Args>(args)的右边,而不是args...意为对每项args展开使用完美转发。

sizeof...运算符

最后还有一个特殊的sizeof...() 运算符(与旧的 sizeof() 运算符无关)会在可变模板参数中使用,以在编译期获取参数个数:

cpp 复制代码
template<typename... Arguments>
void tfunc(const Arguments&... args)
{
    constexpr auto numargs{ sizeof...(Arguments) };

    X xobj[numargs]; // array of some previously defined type X

    helper_func(xobj, args...);
}

以上。

相关推荐
啊董dong13 分钟前
noi-2026年5月12号小测验
数据结构·c++·算法
咩咦1 小时前
C++学习笔记24:构造函数初始化列表
c++·学习笔记·类和对象·构造函数·初始化列表·const引用
计算机安禾1 小时前
【c++面向对象编程】第43篇:可变参数模板(C++11):优雅处理不定长参数
java·开发语言·c++
10岁的博客2 小时前
C++ 进制转换:通用 a 进制转 b 进制(2-36进制)题解
开发语言·c++
小贾要学习2 小时前
【Linux】基于自定义TCP协议的日期计算器
linux·网络·c++·网络协议·tcp/ip
YsyaaabB2 小时前
ACM 模式通用代码模板
java·c++·python·算法
我命由我123453 小时前
C++ - 面向对象 - 析构函数
android·c语言·开发语言·c++·visualstudio·visual studio·android runtime
代码村新手4 小时前
C++-多态
开发语言·c++
玖釉-4 小时前
旋转图像:从矩阵转置、镜像到坐标变换的系统理解
c++·windows·算法·图形渲染
咩咦5 小时前
C++学习笔记23:const 成员函数
c++·学习笔记·类和对象·const·this指针·const成员函数