我在Stroustrup的一本书中找到了这段代码:
void print_book(const vector<Entry>& book)
{
for (const auto& x : book) // for "auto" see §1.5
cout << x << '\n';
}
Run Code Online (Sandbox Code Playgroud)
但const似乎是多余的,因为x会被推断为一个const_iterator,因为book是const在参数.是const auto真的更好吗?
Naw*_*waz 70
在我看来,它看起来很明确,这就是为什么它更好.所以,如果我的意思是const,那么我宁愿明确地写它.它增强了当地的推理,从而帮助其他人比较容易理解的代码-其他程序员不必须看申报的book和推断,x是const为好.
小智 34
代码不仅仅是编译器可以读取的 - 它也适合人类阅读.简洁性只有在不以牺牲可读性为代价时才是好的.
在给定的代码中,推断constness是立即的.根据您提出的更改,推导常量将要求读者准确记住或查看定义book.
如果读者想要了解常数,那么简洁就会适得其反.
And*_* DM 14
看到关键字会更清楚const.您立即意识到它不会被修改,如果const关键字不在那里我们不会知道,除非我们查看函数签名.
const明确地使用关键字对于代码的读者来说要好得多.
此外,当您阅读下面的代码时,您希望它x是可修改的
for (auto& x : book) { ... }
Run Code Online (Sandbox Code Playgroud)
然后,当你尝试修改时,x你会发现它会导致错误,因为它book是const.
在我看来,这不是明确的代码.这是更好的代码来说明x是不是要进行修改,以便其他人阅读代码都会有自己的期待权.
我将在这里采取不同的角度.const并且const_iterator意味着完全不同的东西
const应用于迭代器意味着您无法修改迭代器本身,但您可以修改它指向的元素,就像声明的指针一样int* const.const_iterator意味着你不能修改它指向的元素,但你仍然可以修改迭代器本身(即你可以递增和递减它),就像声明的指针一样const int*.
std::vector<int> container = {1, 2, 3, 4, 5};
const std::vector<int> const_container = {6, 7, 8, 9, 0};
auto it1 = container.begin();
const auto it2 = container.begin();
auto it3 = const_container.begin();
const auto it4 = const_container.begin();
*it1 = 10; //legal
*it2 = 11; //legal
*it3 = 12; //illegal, won't compile
*it4 = 13; //illegal, won't compile
it1++; //legal
it2++; //illegal, won't compile
it3++; //legal
it4++; //illegal, won't compile
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,修改迭代器指向的元素的能力仅取决于它是否为iterator或者const_iterator,并且修改迭代器本身的能力仅取决于迭代器的变量声明是否具有const限定符.
编辑:我刚刚意识到这是一个范围,因此根本没有在这里播放迭代器(至少没有明确说明).x不是迭代器,实际上是对容器元素的直接引用.但是你有正确的想法,const无论是否明确写出,它都会被推断为具有限定符.