【问题标题】:How to select iterator type using auto variable?如何使用自动变量选择迭代器类型?
【发布时间】:2012-03-16 05:44:21
【问题描述】:

我有一个 std::unordered_map

std::unordered_map<std::string, std::string> myMap;

我想使用 find 获得一个 const 迭代器。在 c++03 中我会这样做

std::unordered_map<std::string, std::string>::const_iterator = myMap.find("SomeValue");

在 c++11 中,我想使用 auto 来减少模板

auto = myMap.find("SomeValue");

这是一个 const_iterator 还是迭代器?编译器如何决定使用哪个?有没有办法强制它选择 const?

【问题讨论】:

  • 也许编译器正在做函数范围的类型推断......但是为什么迭代器的常量对你很重要?
  • 除非我对重载的理解是错误的(或者en.cppreference.com/w/cpp/container/unordered_map/find 是错误的),nonConstMap.find 总是返回一个iterator。返回类型和您对结果的处理方式(例如,将其传递给 const_iterator 构造函数)不会影响选择哪个重载。也就是说,如果您调用constMap.find,它只会返回const_iterator

标签: c++ iterator c++11 auto


【解决方案1】:

如果myMap 是非常量表达式,它将使用非常量迭代器。因此你可以说

#include <type_traits>
#include <utility>

template<typename T, typename Vc> struct apply_vc;
template<typename T, typename U> struct apply_vc<T, U&> {
  typedef T &type;
};
template<typename T, typename U> struct apply_vc<T, U&&> {
  typedef T &&type;
};

template<typename T> 
typename apply_vc<typename std::remove_reference<T>::type const, T&&>::type
const_(T &&t) {
  return std::forward<T>(t);
}

然后

auto it = const_(myMap).find("SomeValue");

【讨论】:

  • 为什么不只是template&lt;typename T&gt; const T&amp; const_(T&amp; t) { return t; }
  • 这不适用于非常量右值,并将 const 右值转换为左值。不好。
  • 我没有考虑过后者(为什么要制作 const 已经是 const 的东西?),但无论如何你都会通过重载轻松解决这个问题。右值案例很好,但我仍在努力解决apply_vc 的问题。我知道它的什么,但不知道为什么它是必要的。
  • 它将右值保留为右值,将左值保留为左值,因此成员函数的 ref 限定符重载仍然有效。
  • c++17 已将 std::as_const 添加到标头 link
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多