4

GotW #6 Const-Correctness上的解决方案 4 和 5提到了这一点:

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

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


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

..因为 int 已经是一个右值并且放入 'const' 可能会干扰模板实例化并且会令人困惑、误导并且可能会变胖

我有以下问题

  1. 我们在这里干扰了哪个模板实例化?!
  2. 这里到底有什么误导,为什么?
  3. 为什么非内置和内置之间存在这种区别。我认为这是一个不好的做法!
4

2 回答 2

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

这是不正确的——GotW 中相对较少的错误之一。const右值在 C++03 中是有问题的,在 C++11 中绝对是非常糟糕的。

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

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

需要注意的是,这是不同的原因是因为原始类型总是在语言中内置了特殊的措辞,这使得例如分配给右值是非法的,所以没有必要尝试自己强制执行它const

至于模板实例化,我实际上不确定。当我开始编写 C++ 代码时,这种做法就已经被人们知道是不好的,所以这不是我必须处理的事情。

于 2012-03-18T21:57:38.320 回答
3

就个人而言,我不同意将const返回值独立于移动语义的建议:该值已经是一个右值,因此意外修改它的危险不大。这就是为什么const在非内置类型上放置 a 的部分原因:它们可能包含某种值的后门。例如,std::vector<T>有一个swap()方法可以用来“窃取”非常量右值的内容:

std::vector<int> f();
std::vector<int> value;
f().swap(value);

同样,流有一些成员运算符,允许您将它们与某些内置函数一起使用,这些函数可以有效地从流中提取引用,例如:

std::string word;
std::istringstream("hello, world") >> std::skipws >> word;

没有std::skipws流是一个右值,它不能绑定到的第一个参数,std::operator>> (std::istream&, std::string&)但使用操作符的成员运算符会返回对流的非常量引用。

conston 内置类型实际上根本没有效果。特别是,当将函数的结果传递给函数模板(在 C++2003 中)时,它无法区分传递的返回值const还是非返回值。const因此,它可能看起来好像const对内置返回有影响,但实际上并没有。

正如我所说,我不同意该规则,并且在 C++2011 中它绝对不成立,因为您希望能够移出无论如何都会被const返回阻止的非内置。

于 2012-03-18T22:10:58.713 回答