1--返回引用
同其他引用类型一样,如果函数返回引用,则该引用仅是所引对象的一个别名;则返回结果时不会发生拷贝操作;
不能返回局部对象的引用或指针;因为局部对象在函数结束后会被释放,从而其引用或指针将指向无效的对象或内存区域;
引用返回左值:
函数的返回类型决定函数调用是否是左值,调用一个返回引用的函数得到左值,其他返回类型则得到右值;
下面的例子中,返回值是一个引用,因此其是一个左值,可出现在赋值运算符的左侧:
#include <iostream>
#include <string>
char &get_val(std::string &str, std::string::size_type ix){
return str[ix];
}
int main(int argc, char *argv[]){
std::string s("a value");
std::cout << s << std::endl;
get_val(s, 0) = 'A'; // get_val(s, 0)返回一个引用,其为一个左值
std::cout << s << std::endl;
return 0;
}
2--返回列表
C++11 新标准规定,函数可以返回花括号包围的值的列表;类似于其他返回结果,返回的列表可用来进行初始化;
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> process(std::string A, std::string B){
if(A.empty())
return {};
else if(A == B)
return {A, "equal", B};
else
return {A, "not equal", B};
}
int main(int argc, char *argv[]){
std::string a = "ABC";
std::string b = "DEF";
std::vector<std::string> stat = process(a, b);
for(auto item : stat)
std::cout << item << std::endl;
return 0;
}
3--返回数组指针
因为数组不能被拷贝,所以函数不能返回数组,但可以返回数组的指针或引用;
首先回顾数组与指针的组合:
int arr[10]; // arr是一个含有10个整数的数组
int *p1[10]; // p1是一个含有10个指针的数组,即p1指向一个数组,数组内的元素都是指针;
int (*p2)[10] = &arr; // p2是一个指针,其指向含有10个整数的数组;将(*p2)理解为一个整体,例如用 using tmp = (*p2)替换,则等效于int tmp[10]; tmp是一个含有10个整数的数组,而p2是一个指针,因此其指向含有10个整数的数组;
当定义一个返回数组指针的函数时,数组的维度必须跟在函数名之后,即:
Type ( *function(parameter_list) )[dimension];
int (*func(int i))[10];
// func(int i)表示调用func()函数,其需要一个int型的实参
// (*func(int i))表示可以对函数的返回结果进行解引用
// (*func(int i))[10]表示解引用func的返回结果是一个大小为 10 的数组
// int (*func(int i))[10]表示数组中的元素是 int 类型
在 C++11 新标准中,函数定义可以使用尾置返回类型,其适用于返回类型是数组的指针或者数组的引用,例如:
auto func(int i) -> int(*)[10];
将函数的返回类型放在形参列表之后,可以清楚知道返回的是一个指针(*),其指向一个含有10个整数的数组;