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

Proper syntax to use std::map access operator [] via std::unique_ptr

我的问题很简单。我在谷歌上搜索了很多,但不知何故我无法弄明白。我使用 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++。

手动调用算子函数

my_map->operator[](1)

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

(*my_map)[1]

我觉得 (*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';