通过std :: unique_ptr使用std :: map访问operator []的正确语法

时间:2015-07-29 09:39:04

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

我的问题非常简单。我google了很多,但不知怎的,我无法弄明白。我使用带有std::map的C ++ std::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 ++是受欢迎的,甚至是期望的。

2 个答案:

答案 0 :(得分:11)

手动调用操作员功能

my_map->operator[](1)

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

(*my_map)[1]

答案 1 :(得分:0)

我发现(*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';