[英]Const correctness in C++
I have simple data structure called array
(similar to std::array).我有一个简单的数据结构叫做
array
(类似于 std::array)。 array
class have method called all()
. array
类有名为all()
方法。 Here are method declarations:以下是方法声明:
const range<const_type_pointer> all() const;
range<type_point> all();
range
is class template, which is constructed by two iterators. range
是类模板,由两个迭代器构造而成。 Here is simplified version of range
class declaration:这是
range
类声明的简化版本:
template <typename Iterator>
class range {
typedef typename iterator_traits<Iterator>::type_value type_value;
typedef typename iterator_traits<Iterator>::type_reference type_reference;
typedef typename iterator_traits<Iterator>::type_pointer;
range(Iterator begin, Iterator end);
// methods & algorithms
// data members
mutable Iterator _begin;
mutable Iterator _end;
};
So basically, if I call method all on const array
object, it should call const
overload of method and return const range
.所以基本上,如果我在
const array
对象上调用所有方法,它应该调用方法的const
重载并返回const range
。 Now, in my algorithms section, I have simple algorithm with following signature:现在,在我的算法部分,我有带有以下签名的简单算法:
template <typename UnaryFunction>
range forEach(UnaryFunction function);
Then I tried following test:然后我尝试了以下测试:
void test1(const array<int, 10>& array)
{
auto r = array.all();
r.forEach([](int i) { std::cout << i << " "; });
}
And second one:第二个:
void test2(const array<int, 10>& array)
{
auto r = array.all();
r.forEach([](int& i) { ++i; });
}
In first case, where I was just printing variable i
, compiler did not complained, even though I called non- const range
method on const range
object.在第一种情况下,我只是打印变量
i
,编译器没有抱怨,即使我在const range
对象上调用了非const range
方法。 In second case, compiler complained.在第二种情况下,编译器抱怨。 Is this behaviour standard confornant?
这种行为是否符合标准?
As a compiler, I am using MSVS compiler.作为编译器,我使用的是 MSVS 编译器。
auto
works just like template argument deduction, which means that it drops top-level references and top-level const
& volatile
qualifiers. auto
就像模板参数推导一样工作,这意味着它删除顶级引用和顶级const
和volatile
限定符。 In other words, your r
is of type range<const_pointer_type>
in both cases.换句话说,在这两种情况下,您的
r
都是range<const_pointer_type>
类型。
Returning a const
-qualified object should only be done in very special circumstances when you understand all details of its behaviour and really know that you want them.只有在非常特殊的情况下,当您了解其行为的所有细节并真正知道您想要它们时,才应该返回一个
const
限定的对象。
Normally, you should just return objects without cv-qualifiers.通常,您应该只返回没有 cv 限定符的对象。 It will play nicer with move semantics, and will not lead to incorrect expectations.
它会更好地使用移动语义,并且不会导致不正确的期望。
First.第一的。 Sice you are returning by value, it doesn't really make any difference if you are returning
const range
or range
.由于您是按值返回,因此返回
const range
或range
并没有什么区别。
Second.第二。
auto r = array.all();
creates a copy of whatever was returned by all
.创建
all
返回的任何内容的副本。 Your r is a non-const object, and non-const forEach
is used.您的 r 是一个非常量对象,并且使用了非常量
forEach
。 But since the iterator is const in the second version, you can't modify the iterable.但是由于迭代器在第二个版本中是 const ,因此您无法修改可迭代对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.