0

I defined a class as follow.

class Camera
    {
      public:
        explicit Camera(const CameraParams& camera_params);

        DataFrame capture();

      private:
        std::unique_ptr<CameraInterface> ptr_;
        bool get_color_;
        bool get_depth_;
        bool get_normals_;
        bool get_point_cloud_;
    };

I want to add it to a map. So I did following.

  std::map<std::string, Camera> cameras_;

  for (auto& camera_params : params.camera_params_vec)
    {
        cameras_[camera_params.name] = Camera(camera_params);
    }

There are two problems with this code. (1) No default constructor, so compile failed. But I don't want to defined a meaningless default constructor just for adding to map. (2) Camera class includes a unique pointer. I don't know how to move it to map correctly.

What is a good practice to solve this kind of problem?

suihe dolood
  • 101
  • 6
  • 1
    Then don't use `operator[]` which requires a default CTOR, use `emplace` or better `try_emplace` which has no such preconditions. – Quimby Jun 28 '23 at 06:14
  • 1
    You could answer this kind of question for yourself with the help of a [good reference](https://en.cppreference.com/w/cpp/container/map). Seems like your understanding is good enough to benefit from a comprehensive C++ reference. – john Jun 28 '23 at 06:23

2 Answers2

3

You write it as

std::map<std::string, Camera> cameras_;

for (auto& camera_params : params.camera_params_vec)
{
    cameras_.emplace(camera_params.name, Camera(camera_params));
}

There is a subtle difference, though: in the original version, the new object is assigned to the key regardless of whether it existed in the map before. This version only assigns the new key if it did not exist before, otherwise, it leaves the original in place and throws away the new object.

j6t
  • 9,150
  • 1
  • 15
  • 35
  • I wouldn't call that a subtle difference. In any case the method `insert_or_assign` exists (since C++17) to simulate operator[] – john Jun 28 '23 at 06:17
0

std::map<std::string, std::shared_ptr<Camera>> would seem like the obvious solution to me. std::shared_ptr has an operator bool() method for easy testing if it hasn't been allocated yet.

Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
  • 2
    Using a shared pointer just to avoid needing a default constructor seems a bit heavy handed. You'll also end up filling your map with null pointers every time you do `if (map[somekey])` – Alan Birtles Jun 28 '23 at 06:22