ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第7章 按值传递或按引用传递:7.5 处理返回值

2020-05-03 16:01:16  阅读:246  来源: 互联网

标签:std 返回 return 按值 reference auto 传递 引用 7.5


7.5 Dealing with Return Values

7.5 处理返回值

 

For return values, you can also decide between returning by value or by reference. However, returning references is potentially a source of trouble, because you refer to something that is out of your control. There are a few cases where returning references is common programming practice:

函数的返回值也可以按值或按引用返回。但是如果按引用返回,可能会潜在一些问题。因为你引用的对象可能是一个己经失去控制的东西。在以下几种情况中,返回引用是一种常见的编程经验:

  • Returning elements of containers or strings (e.g., by operator[] or front())

  返回容器或字符串中的元素(如,通过[ ]运算符或front()函数)

  • Granting write access to class members

  允许修改类对象的成员

  • Returning objects for chained calls (operator<< and operator>> for streams and operator= for class objects in general)

  为链式调用返回一个对象(例如流操作中的<<或>>运算符,以及赋值运算符)

In addition, it is common to grant read access to members by returning const references.

此外,通常通过返回const引用,来授权对类成员的只读访问权。

Note that all these cases may cause trouble if used improperly. For example:

但是如果使用不当,以上几种情况就可以引发一些问题,例如:

std::string* s = new std::string("whatever");
auto& c = (*s)[0];
delete s;
std::cout << c; //ERROR:运行期错误

Here, we obtained a reference to an element of a string, but by the time we use that reference, the underlying string no longer exists (i.e., we created a dangling reference), and we have undefined behavior. This example is somewhat contrived (the experienced programmer is likely to notice the problem right away), but things easily become less obvious. For example:

这里声明了一个指向字符串中元素的引用。但是当我们使用该引用时,其底层字符串己经不存在了(即,我们创建了一个“悬挂引用”),这会导致未定义行为。这个例子有些人为设计(有经验的程序员可能马上就会注意到这个问题),但事情很容易变得不那么明显。例如:

auto s = std::make_shared<std::string>("whatever");
auto& c = (*s)[0];
s.reset();
std::cout << c; //run-time ERROR

We should therefore ensure that function templates return their result by value.

因此,我们应该确保函数模板按值返回结果。

 

However, as discussed in this chapter, using a template parameter T is no guarantee that it is not a reference, because T might sometimes implicitly be deduced as a reference:

但是,正如本章所讨论的那样,使用模板参数T作为返回类型并不能保证不会返回引用,因为T在某些情况下会被隐式的推导为引用

template<typename T>
T retR(T&& p) // p is a forwarding reference
{
    return T{…}; // OOPS: 当传入左值时,返回T&类型。    
}

Even when T is a template parameter deduced from a call-by-value call, it might become a reference type when explicitly specifying the template parameter to be a reference:

就算在模板中,T被声明为按值传递,也可以显式地将T指定为引用类型:

template<typename T>
T retV(T p) //Note: T might become a reference
{
    return T{…}; // OOPS: returns a reference if T is a reference
}

int x;
retV<int&>(x); // retT() instantiated for T as int&

To be safe, you have two options:

安全起见,你有两种选择:

• Use the type trait std::remove_reference<> (see Section D.4 on page 729) to convert type T to a nonreference:

  使用std::remove_reference<>(见第729页的D.4节)来将类型T转换为非引用类型:

template<typename T>
typename std::remove_reference<T>::type retV(T p)
{
    return typename std::remove_reference_t<T>{…}; // always returns by value
}

Other traits, such as std::decay<> (see Section D.4 on page 731), may also be useful here because they also implicitly remove references.

当然也可以用其他类型萃取,如std::decay<>可能也有用(见第731页的D.4节),因为它们隐式地将引用移除。

• Let the compiler deduce the return type by just declaring the return type to be auto (since C++14; see Section 1.3.2 on page 11), because auto always decays:

  将返回类型声明为auto,让编译器去推断返回类型。这是因为auto会导致类型退化(从C++14开始,请参阅第11页的1.3.2)。

template<typename T>
auto retV(T p) // by-value return type deduced by compiler
{
    return T{…}; // 总是按值返回
}

 

标签:std,返回,return,按值,reference,auto,传递,引用,7.5
来源: https://www.cnblogs.com/5iedu/p/12822225.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有