为什么按值返回对于非内置类型应该是 const 而对于内置类型不是 const ? [英] Why should return-by-value be const for non-builtin types but not const for builtin types?

查看:32
本文介绍了为什么按值返回对于非内置类型应该是 const 而对于内置类型不是 const ?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于 GotW #6 Const-Correctness<的解决方案 4 和 5/strong> 提到这一点:

<块引用>

Point GetPoint( const int i ) {返回点_[i];}

对于非内置返回类型,按值返回通常应该是 const ..


int GetNumPoints() {返回points_.size();}

.. 因为 int 已经是一个右值,并且放入 'const' 会干扰模板实例化,并且会造成混淆、误导,并且可能会使人变胖.

我有以下问题

  1. 我们在这里干扰了哪些模板实例化?!
  2. 这里究竟有什么误导性以及为什么?
  3. 为什么要区分非内置函数和内置函数.我认为这是一个不好的做法!

解决方案

对于非内置返回类型,按值返回通常应该是 const ..

那是不正确的 - GotW 中相对较少的错误之一.const 右值在 C++03 中是有问题的,在 C++11 中肯定非常糟糕.

问题是在 C++03 中,右值可以调用任何成员函数——甚至是非常量.这很棒,因为您可以交换"或执行方法链和其他事情,这非常好且绝对有意义,但也很糟糕,因为当您执行一些愚蠢的操作时,编译器无法抓住您,例如分配给它或其他东西.一般来说,限制每个人做好事是一个坏主意,因为调用者可能做一些愚蠢的事情.意图是好的,但不对.

在 C++11 中,这是固定的,因为您可以禁止在右值上调用成员函数,其次,因为为了使移动语义正确工作,右值必须是可变的.如果右值是 const,则不能从右值中获取资源.

请注意,之所以不同,是因为原始类型总是在语言中内置了特殊的措辞,例如分配给右值是非法的,因此没有必要通过将其设置为 const 来尝试和强制执行.

至于模板实例化,我实际上不确定.在我开始编写 C++ 代码的时候,这种做法已经被人们知道是不好的,所以我从来不需要处理它.

Solutions 4 and 5 on GotW #6 Const-Correctness mention this:

Point GetPoint( const int i ) {
    return points_[i];
}

Return-by-value should normally be const for non-builtin return types ..


int GetNumPoints() {
    return points_.size();
}

.. since the int is already an rvalue and to put in 'const' can interfere with template instantiation and is confusing, misleading, and probably fattening.

I have the following questions

  1. Which template instantiation are we interfering with here ?!
  2. What exactly is misleading here and why?
  3. Why this differentiation between non-builtins and builtins. I thought this was a bad practice!

解决方案

Return-by-value should normally be const for non-builtin return types ..

That is not correct- one of the relatively few mistakes in the GotW. const rvalues were questionable in C++03 and definitely very bad in C++11.

The problem is that in C++03, rvalues can have any member function called on them- even non-const. This is great because you can "swaptimize" or perform method chains and other things, which are perfectly fine and make absolute sense, but it's also bad because the compiler can't catch you when you do something stupid, like assign to it or something. Generally, it's a bad idea to restrict everyone from doing good things because the caller might do something stupid. The intention is good, but it's not right.

In C++11 this is fixed because you can disallow member functions from being called on rvalues, and secondly, because in order for move semantics to work correctly the rvalue must be mutable. You can't take resources from an rvalue if it's const.

Just as a note, the reason this is different is because primitive types have always had special wording built into the language which made e.g. assigning to rvalues illegal, so there was no need to try and enforce that yourself by making it const.

As for the template instantiations, I'm actually uncertain. This practice was already known to be bad by the time I started coding C++, so it's not something I ever had to deal with.

这篇关于为什么按值返回对于非内置类型应该是 const 而对于内置类型不是 const ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆