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