10월 28, 2019 · C++ developemnt

gcc 4.8.5에서 emplace가 안될 때

Key-Value 형식의 STL Container에서 각각의 Key-Value 쌍은 std::pair<Key, Value> 형태로 이루어진다. std::pair의 생성자 중 하나는 각각의 Key, Value 타입의 forwarding reference (또는 Universal reference)를 받는다. 따라서 STL Container에서 emplace를 활용하면 Key와 Value의 값을 전달해서 삽입할 수 있다. (C++11부터 r-value reference로 인해 pair 객체를 사용해도 똑같을 것이긴 하다.) 이 때, Key와 Value의 생성자에 임의의 타입 A와 B를 각각 받는 경우가 있다고 가정하면, emplace에 Key와 Value의 객체를 명시적으로 생성할 필요 없이, A와 B의 객체의 전달만으로도 생성할 수 있을 것이다.


class A {};
class B {};

struct Key {
    Key(const A& a) {}
};

struct Value {
    Value(const B& a) {}
};

std::unordered_map<Key, Value> associative_container;

A a_instance;
B b_instance;

associative_container.emplace(a_instance, b_instance);

하지만위코드는 gcc 4.8.5에서컴파일되지않았다.(CentOS7기준)이를해결하기위해선다른방법들이있을것이지만,std::pair의다른생성자를사용하여해결하기로했다.std::pair는첫번째인자가 std::piecewise_construct_t 타입일경우, tuple 2개를받아각각의 tuple로부터Key와Value객체를생성할수있다.이를 emplace에적용시켜서사용하면다음과같다.

associative_container.emplace(
    std::piecewise_construct,
    std::forward_as_tuple(a_instance),
    std::forward_as_tuple(b_instance)
);

위와같은접근법은생성자가2개이상인경우에도 emplace를호출하기위해사용했으나,1개의경우에도빌드가되지않아서적용시켰다.