C++返回vector/将vector作为参数传递

本文介绍了在C++中如何通过vector实现函数返回多个值的方法,包括使用引用传递和直接返回vector两种方式,并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C++里很多时候我们会遇到函数想返回两个以上结果的情况,这时候可以用数组(vector)、类来作为容器返回,也可以声明一个全局变量的数组,将数值存放在数组里解决。

第一个方式是使用引用来解决,将vector的引用在函数间传递

这是一个例子,假设我要传入一个数,我的函数的功能是返回这个数后面十个数的序列。

#include<iostream>
#include<vector>
using namespace std;

/*
输入一个数,返回这个数后面的十个数字序列
注意参数的这个 & 符号不能省略
*/ 
void getSequence(int num,vector<int>& sequence){
    for(int i=0;i<10;i++){
        sequence.push_back(i+num);
    }
}

int main(){
    int num=9;
    vector<int> sequence;
    //在主调函数这边,直接传入该vector变量
    getSequence(num,sequence);
    //访问该vector的值的时候,也是直接访问即可
    for(vector<int>::iterator it=sequence.begin();it!=sequence.end();it++){
        cout<<*it<<endl;
    }
}

第二个方式是返回vector变量

在被调用函数中声明一个vector变量,函数结束的时候返回vector变量
但是这样的传参方式我有一个不太理解的地方,既然vector变量是在被调函数中声明的,就应该是一个局部变量,在被调函数执行完毕之后这部分空间应该会被销毁,这个变量就无法访问到了,莫非vector是在堆空间开辟的地址?然后返回的其实是指向堆空间vector的指针?

vector<int> getSequence(int num){
    vector<int> sequence;
    for(int i=0;i<10;i++){
        sequence.push_back(i+num);
    }
    return sequence;
}

int main(){
    int num=9;
    vector<int> sequence;
    //在主调函数这边,只传入num 
    sequence=getSequence(num);
    //访问该vector的值的时候,也是直接访问即可
    for(vector<int>::iterator it=sequence.begin();it!=sequence.end();it++){
        cout<<*it<<endl;
    }
}

<think>我们正在讨论C++11中vector作为默认参数的问题。在C++11及更高版本中,我们可以使用初始化列表来设置默认参数。以下是关键点:1.使用空初始化列表`{}`作为默认值是最简单且安全的方式,因为每次调用函数时都会构造一个新的空vector。这避免了静态对象的线程安全问题。 2.也可以使用临时对象作为默认参数,尤其是在常量引用传递的情况下。3.注意默认参数必须在函数声明中指定,且必须是编译时常量或全局对象。下面给出具体示例:###正确用法示例(C++11及以上)**值传递+空初始化列表**```cpp#include<vector> voidprocess_data(std::vector<int> data= {}) {//使用data} ```**常量引用 +临时对象**```cpp#include<vector> voidprocess_data(const std::vector<int>&data =std::vector<int>()){//使用data}``` **使用静态全局空向量**```cpp#include<vector> staticconst std::vector<int>EMPTY_VECTOR; //全局静态空向量voidprocess_data(const std::vector<int>&data =EMPTY_VECTOR) {//使用data} ```###注意事项-在C++11之前,不能使用初始化列表`{}`,但C++11及以后支持。 -避免使用非静态局部变量作为默认参数,因为这是非法的。-默认参数在每次调用时都会求值,因此使用`{}`会构造一个新的vector,但空vector的构造是轻量级的。 -如果默认参数是一个大型vector,则每次调用都会产生复制开销,因此在这种情况下,建议使用引用传递并设置一个全局静态常量vector(但要注意线程安全,如果只是只读则线程安全)。###错误示例```cpp//错误:非静态局部变量不能作为默认参数voidbad_function() {std::vector<int>local_vec;void another_function(std::vector<int> vec= local_vec);//错误}//错误:默认参数必须在函数声明中指定,且不能是局部变量``` ###C++11新特性带来的便利C++11的初始化列表使得默认参数的设置更加简洁,尤其是对于容器类。§§相关问题§§1.在C++11中,除了vector,其他容器如map、set等如何设置默认参数?2.当默认参数是一个非空的vector时,如何正确设置以避免重复构造?3.使用全局静态vector作为默认参数时,如何确保其在多线程环境下的安全性?4. C++11的初始化列表`{}`是否可以用作所有类型的默认参数?5.在函数模板中,如何为vector类型的模板参数设置默认值?</think>### C++11 中 vector 作为默认参数的实现方法 在 C++11 及更高版本中,`std::vector` 作为函数默认参数有更简洁安全的实现方式: #### 推荐方法 (C++11 特性) 1. **空初始化列表语法** ```cpp void process(std::vector<int> data = {}) { // 函数体 } ``` - 每次调用创建新的空 vector - 线程安全且无静态对象依赖 - 语法最简洁 (C++11 起支持) 2. **临时对象作为默认参数** ```cpp void print(const std::vector<std::string>& items = std::vector<std::string>{}) { // 函数体 } ``` - 临时对象生命周期延长至函数结束 - 适用于引用传递场景 3. **自定义默认值** ```cpp void init(std::vector<int> values = {1, 2, 3}) { // 带初始值的默认参数 } ``` - 使用初始化列表指定非空默认值 - 注意大型容器可能带来构造开销 #### 关键注意事项 - **编译期求值**:默认参数必须在编译期可确定 - **头文件声明**:在函数声明处指定默认值 - **类型匹配**:默认值类型必须精确匹配参数类型 - **移动语义**:C++11 的移动构造减少值传递开销 - **统一初始化**:优先使用 `{}` 而非 `()` 避免歧义 #### 错误示例 ```cpp // 错误:局部变量不能作为默认参数 void invalid() { auto local = std::vector{5, 10}; void func(std::vector<int> v = local); // 编译错误 } // 危险:非const静态对象 static std::vector<int> cache; void unsafe_func(std::vector<int>& data = cache) { data.push_back(42); // 多线程下危险 } ``` #### 最佳实践 1. 优先使用 `= {}` 空初始化语法 2. 大型容器使用常量引用传递 3. 避免可变静态对象作为默认参数 4. 复杂默认逻辑改用函数重载替代
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值