2017-11-25 25 views
3

왜 unique_ptr과 함께지도의 중괄호 초기화를 사용할 수 없습니까?C++지도 중괄호 초기화 및 고유 ptr

편집 : g ++ 7.2를 C++ 17 모드로 사용합니다.

make_pair와 [] 연산자를 사용하여 정렬되지 않은 맵에 만들고 삽입 할 수 있습니다.

std::unordered_map<std::string, std::unique_ptr<A>> map; 

map.insert(std::make_pair("hello",std::make_unique<A>())); 
map["foo"] = std::make_unique<A>(); 

하지만 중괄호를 사용할 때 왜 실패하는지 알 수 없습니다.

map.insert({"foo", std::make_unique<A>()}); // Error 

error: use of deleted function ‘std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&)

+1

C++ (17) 우리는 또한이 대신

. – Rakete1111

+1

afaik 삽입 사본 (unique_ptr은 복사 불가), emplace – Sopel

답변

1

C++ 11 연관 컨테이너 삽입하거나 필요하므로 복사 costructiblelvalues ​​또는 이동 도입 가변 우변. 따라서 insert()make_pair()과 함께 호출해도 아무런 문제가 없습니다. 후자는 value_type 직사각형을 초기화하는 데 사용되는 pair<const char[],unique_ptr>을 생성합니다. , 따라서 사본이 요청 (데에는 적절한 VALUE_TYPE & & 과부하 없기 때문에) 및 에러가 발생

브레이스 초기화의 문제점 (17 C++까지)를 VALUE_TYPE CONST & 과부하 바람직 도착이다.

사실 두 양식 모두 gcc trunk에서 컴파일되고 C++ 17 모드에서는 libC++로 컴파일됩니다.


보다 정확하게는 관련 시맨틱 삽입 요구

[unord.req] If t is a non-const rvalue expression, value_type shall be MoveInsertable into X; otherwise, value_type shall be CopyInsertable into X.

물건이 다른 실 부재 사양 판독에 C++ 11; C++ 17까지, 우리는이 :

pair<iterator, bool> insert(const value_type& obj); 
template <class P> pair<iterator, bool> insert(P&& obj); 
... 

일반 과부하가 SFINAE이 std::is_constructible<value_type, P&&>::value로 제한된다. 분명히 braced-init-list을 사용하면 여기서 &의 과부하를 선택할 수 있습니다 (참고 : initializer_list 오버로드가 있지만 OP 케이스에는 적용되지 않습니다). 더`표준 : make_unique`이 없었 전에 때문에, C++ 14을 사용하는

pair<iterator, bool> insert(value_type&& obj); 
+0

은 gcc 지원과 유사합니다. C++ 17은 여전히 ​​실험적이므로 (https://gcc.gnu.org/projects/cxx-status.html) 나를 위해 컴파일 (gcc 7.2). 좋은 설명. 감사. –