C++ 这个';自动';关键字知道何时使用常量迭代器匹配函数重载吗?

C++ 这个';自动';关键字知道何时使用常量迭代器匹配函数重载吗?,c++,c++11,constants,auto,overloading,C++,C++11,Constants,Auto,Overloading,我理解的内容,但当使用函数重载时,事情是如何工作的 例如,在std::map中定义了以下方法: iterator find (const key_type& k); const_iterator find (const key_type& k) const; 如何使用auto关键字选择一个或另一个?在我看来,以下情况似乎不正确: auto i = mymap.find(key); //calls the non-const method? const

我理解的内容,但当使用函数重载时,事情是如何工作的

例如,在
std::map
中定义了以下方法:

      iterator find (const key_type& k);
const_iterator find (const key_type& k) const;
如何使用
auto
关键字选择一个或另一个?在我看来,以下情况似乎不正确:

auto i = mymap.find(key);        //calls the non-const method?
const auto i = mymap.find(key);  //calls the const method?
std::map可变映射;
const std::map const_map;
可变_映射。查找(1);//返回迭代器
常量映射。查找(1);//返回常量迭代器
您不希望从常量
map
返回常规迭代器,因为这会破坏常量。因此,让
find
成员函数合理地处理常量
map
s的唯一方法是让
const
重载返回
const\u迭代器

在c++14中,您将拥有并强制使用const\u迭代器getter

要对map的find方法执行同样的操作,您需要const_cast,但语法很糟糕,或者只是一个小助手

#include <iostream>
#include <map>

template <typename T> T const &  ccast( T const & v )  { return v; }
template <typename T> T const && ccast( T const && v ) { return v; }

int main() {
    using Map = std::map<int,int>;
    Map map;

    static_assert( std::is_same< decltype(map.find(1)), Map::iterator >::value, " mutable map give mutable iterator" );
    static_assert( std::is_same< decltype(const_cast<Map const&>(map).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );

    static_assert( std::is_same< decltype(ccast(map).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );
    static_assert( std::is_same< decltype(ccast(std::move(map)).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );
}

那太晚了,LHS没有参与重载解析。@marglisse你是说使用
const_迭代器i=mymap.find(key)它甚至不起作用?那么让函数重载有什么意义呢?
autoit=as_const(map).find(…)
@DarioP,因为
迭代器
可转换为
常量迭代器
,它调用非常量重载。当
mymap
本身是const时,使用const重载。@Xeo这是标准的吗?它的用法会被典型的const正确性规则所建议吗?我已经在c++11中使用了cbegin和cend,也许它们只是别名。看来你把事情弄得太复杂了。一旦定义了
&ccast
,就可以直接使用它
autoit=ccast(map)在这种情况下,右值引用看起来毫无用处。最后,如果调用
autoconst it=map.find(1)
您将不会得到
常量迭代器
(无法更改项值),而是
常量迭代器
(无法更改所指向的项)。@DarioP右值引用版本是为了完整性,它不会更改此处的结果,但对于具有基于引用类型的方法重载的对象,它很重要
struct A{int foo()&;int foo()&&&}
@DarioP,在const_iterator魔术演员阵容中做白日梦…
const iterator
!=<代码>常量迭代器
。前者类似于
T*const
,后者类似于
T*const*
。关键是您可能需要一个带有可变映射的
const\u迭代器。因此,可能是隐式转换或函数:
template constepr const T&as_const(T&T){return T;}
用于在编译时动态获取将返回const_迭代器的const引用。
#include <iostream>
#include <map>

template <typename T> T const &  ccast( T const & v )  { return v; }
template <typename T> T const && ccast( T const && v ) { return v; }

int main() {
    using Map = std::map<int,int>;
    Map map;

    static_assert( std::is_same< decltype(map.find(1)), Map::iterator >::value, " mutable map give mutable iterator" );
    static_assert( std::is_same< decltype(const_cast<Map const&>(map).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );

    static_assert( std::is_same< decltype(ccast(map).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );
    static_assert( std::is_same< decltype(ccast(std::move(map)).find(1)), Map::const_iterator >::value, "const map give imutable iterator" );
}
auto const it = map.find(1);
it++ // compilation error
std::for_each( it, end(map), /**/ ); // compilation error too