programing

인수가없는 생성자가있는 객체를 std :: map에 배치하는 방법은 무엇입니까?

itsource 2021. 1. 15. 08:12
반응형

인수가없는 생성자가있는 객체를 std :: map에 배치하는 방법은 무엇입니까?


std::map생성자가 인수를 사용하지 않는 객체를에 배치하고 싶습니다 . 그러나 std::map::emplace키 외에 추가 인수가 하나 이상 필요한 것 같습니다. 그렇다면 어떻게 제로 인수를 생성자에 전달할 수 있습니까?


의 요소 유형 std::map<K, V>은 실제로입니다 std::pair<K, V>. 따라서지도에 배치 할 때 인수가의 생성자에 전달됩니다 std::pair. 이것이 바로 키를 전달할 수없는 이유 std::pair<K, V>입니다. 단일 인수로 구성 할 수 없습니다 (동일한 유형의 다른 쌍이 아닌 경우). 인수 0 개를 전달할 수 있지만 키는 값으로 초기화됩니다. 당신이 원하는 것이 아닙니다.

대부분의 경우 값을 이동하는 것은 저렴하며 (키는 작고 복사 할 수 있음) 실제로 다음과 같이해야합니다.

M.emplace(k, V{});

V매핑 된 유형은 어디에 있습니까 ? 값이 초기화되고 컨테이너로 이동됩니다. (이동이 생략 될 수도 있지만 확실하지 않습니다.)

움직일 수없고 V제자리에를 생성해야한다면 조각 별 생성자를 사용해야합니다.

M.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple());

이로 인해 std::pair첫 번째 요소는을 사용 k하고 두 번째 요소는 0 인수를 사용하여 생성됩니다 (값 초기화).


를 명시 적으로 만들어에 pair전달 map::emplace하거나의 조각 별 생성 생성자 를 사용할 수 std::pair있습니다.

struct foo {};

std::map<int, foo> m;

m.emplace(std::pair<int, foo>(1, {}));
m.emplace(std::piecewise_construct,
          std::forward_as_tuple(2),
          std::forward_as_tuple());

라이브 데모


내가 만들했을 때 저도 같은 문제를 겪고 std::mapstd::mutex객체. 문제는 std::mutex복사 나 이동이 불가능하기 때문에 "제자리에"구성해야했습니다.

이 경우 허용되는 대답은 작동하지 않습니다 ( M.emplace(k, V{});V가 이동 가능해야 함). 그리고 복잡하고 읽기 어려운 std::piecewise_construct옵션 을 사용하고 싶지 않았습니다 (위의 다른 답변 참조).

내 솔루션은 훨씬 간단합니다. 사용하기 만하면 operator[]기본 생성자를 사용하여 값을 만들고 이에 대한 참조를 반환합니다. 또는 새 항목을 만들지 않고 기존 항목에 대한 참조를 찾아서 반환합니다.

std::map<std::string, std::mutex> map;

std::mutex& GetMutexForFile(const std::string& filename)
{
    return map[filename]; // constructs it inside the map if doesn't exist
}

C ++ 17 std::map::try_emplace에서는 std::piecewise_construct내부적으로 사용 하고 번거롭지 않은를 사용할 수 있습니다 . 또한 키를 첫 번째 인수로 사용합니다 (모든 것을 std::pair::pair()같은 방식 으로 전달하는 대신 emplace).

#include <map>

struct A {
    A() = default;
};

int main()
{
    std::map<int, A> map;

    map.emplace(std::piecewise_construct,
                std::forward_as_tuple(10),
                std::forward_as_tuple());
    // ...vs...
    map.try_emplace(10);
}

라이브 예 .


Class ToolMap() 
{
 friend class std::map;
  public (std::map)Object ToolMap()
  {
     return Object;
  }

}

참조 URL : https://stackoverflow.com/questions/27553776/how-to-emplace-object-with-no-argument-constructor-into-stdmap

반응형