【问题标题】:Proper syntax to use std::map access operator [] via std::unique_ptr通过 std::unique_ptr 使用 std::map 访问运算符 [] 的正确语法
【发布时间】:2015-07-29 09:39:04
【问题描述】:

我的问题很简单。我用谷歌搜索了很多,但不知何故我无法弄清楚。我使用 C++ std::mapstd::unique_pointer,如下所示:

std::unique_ptr<std::map<int,std::string>> my_map( new std::map<int,std::string>());

现在,我想使用地图的访问运算符[]。但我总是遇到编译器错误。

my_map[1] = "XYZ";    // error C2676
my_map->[1] = "XYZ";  // error C2059

没有std::unique_ptr,我的代码将如下所示,并且可以正常工作。但是我如何通过std::unique_ptr 做同样的事情?请帮帮我。

std::map<int,std::string> my_map;
my_map[1] = "XYZ";   // OK!

现代 C++ 是受欢迎的,甚至是需要的。

【问题讨论】:

  • 请注意,还有at() 方法,使用指针可能更“优雅”,my_map-&gt;at(1)

标签: c++ c++11 c++14 unique-ptr stdmap


【解决方案1】:

手动调用算子函数

my_map->operator[](1)

或取消引用指针并调用operator []

(*my_map)[1]

【讨论】:

  • 太好了,两种方法都对我有用!正是我想要的!
【解决方案2】:

我觉得(*my_map)[1] 很烦人。问题是操作顺序。

我们可以使用命名运算符来反转操作顺序,如下所示:

namespace easy_op {
  enum class supported_ops {
    index,
    invoke,
  };
  template<class Rhs, supported_ops>
  struct op_t {
    Rhs rhs;
  };
  constexpr static struct do_opt {
    template<class Rhs>
    constexpr op_t<Rhs, supported_ops::index>
    operator[](Rhs&& rhs)const{
      return {std::forward<Rhs>(rhs)};
    }
    template<class Rhs>
    constexpr op_t<Rhs, supported_ops::invoke>
    operator()(Rhs&& rhs)const{
      return {std::forward<Rhs>(rhs)};
    }
    constexpr do_opt() {}
  } const op;
  template<class Lhs, class Rhs>
  constexpr auto operator*( Lhs&& lhs, op_t<Rhs, supported_ops::index>&& rhs )
  -> decltype( (*std::declval<Lhs>())[std::declval<Rhs>()] )
  {
    return (*std::forward<Lhs>(lhs))[std::forward<Rhs>(rhs.rhs)];
  }
  template<class Lhs, class Rhs>
  constexpr auto operator*( Lhs&& lhs, op_t<Rhs, supported_ops::invoke>&& rhs )
  -> decltype( (*std::declval<Lhs>())(std::declval<Rhs>()) )
  {
    return (*std::forward<Lhs>(lhs))(std::forward<Rhs>(rhs.rhs));
  }
}
using easy_op::op;

live example.

std::unique_ptr< std::vector<int> > p = std::make_unique<std::vector<int>>();
*p = {0,1,2,3,4,5};
for(std::size_t i = 0; i < p->size(); ++i) {
    std::cout << p*op[i];
}
std::cout << '\n';

【讨论】:

  • (*p)[i] 可能很烦人,但它的含义很明显,与p*op[i] 形成鲜明对比(顺便说一句,至少同样烦人)
  • @Walter 好点。也许我应该重载p-&gt;*[i]。 ;)
猜你喜欢
  • 2018-01-28
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
相关资源
最近更新 更多