推导出类型"auto it = unordered_map.find(key)"?

Dej*_*avu 6 const-iterator c++11

随着C++ 11的出现,我们有unordered_map.cbegin/cend来专门返回const_iterator的值.所以在表达式"auto it = unordered_map.cbegin()"中推导出的'it'类型是const_iterator.

但是,当谈到unordered_map.find(key)函数时,我认为可能缺少一个"cfind()"对应物,它特意返回一个const_iterator.

有人说我们可以使用"const auto it = unordered_map.find(key)"来获取"const迭代器",但我强烈怀疑"const iterator"是相同的"const_iterator",其中"const iterator"的限制改变迭代器本身的能力,而"const_iterator"限制了改变迭代器引用的内容的能力.

所以,真的,如果我们想充分利用"自动"类型演绎(了解混淆或"自动"类型演绎的变化 - auto,auto&,const auto等),我怎么能有unordered_map .find(key)返回一个"const_iterator"而不必我明确指定"const_iterator" - 这就是auto的所有最佳用例之后!

下面是一个演示编译器行为的简单示例代码:

#include "stdafx.h"
#include <unordered_map>

int _tmain(int argc, _TCHAR* argv[])
{
    typedef std::unordered_map<int, int> umiit;
    umiit umii;

    auto it0 = umii.find(0);
    it0->second = 42;
    const auto it1 = umii.find(0);
    it1->second = 42;
    umiit::const_iterator it2 = umii.find(0);
    it2->second = 42; // expected compiler error: assigning to const

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*son 1

我不知道有哪个地方需要 aconst_iterator而你不能简单地传递 aniterator来代替,所以这个缺陷可能不会对日常代码编写造成太大干扰。然而,为了一般通信的利益,我确实更喜欢在不需要变异的地方使用const_iterators (一般来说),所以我认为添加 a可能是对未来标准库的有用补充。constcfind()

不过,我认为这段代码可以作为您想要实现的目标的简单解决方法:

template<typename T>
auto use_as_const( T const &t ) -> T const & {
    return t;
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的转换包装函数,其风格与move()和类似forward<T>(),用于提供(并记录)对象的单独使用的约束。然后你可以像这样使用它:

auto it1 = use_as_const( umii ).find(0);
Run Code Online (Sandbox Code Playgroud)

这也可以用来代替依赖cbegin()cend()。或者,它可以用于基于范围的 for 循环:

for ( auto &element : use_as_const( some_vector_of_string ) ) {
    cout << element;
    // element = ""; // This line shouldn't compile.
}
Run Code Online (Sandbox Code Playgroud)

在上面的循环示例中,虽然我通常更喜欢auto const &element : ...,但我相信这是不必要的,并且element仍然会被推导为 const 引用。