std :: unordered_map <T, std :: unique_ptr <U >> копируемый? Ошибка GCC?

g++ --version выходы:

g++.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Программа:

#include <memory>
#include <type_traits>
#include <unordered_map>

static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");

int main () {   }

Результат компиляции:

.\unorderedmapcopyable.cpp:5:1: error: static assertion failed: Copyable
 static_assert(!std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>>>::value,"Copyable");
 ^

Соответствующий стандарт:

На контейнерах, которые можно копировать

Для заявленийX u(a) а такжеX u=a быть действительным для некоторого типа контейнераX, который содержит типT, гдеa это значение типаX:

Требуется: T являетсяCopyInsertable вX

§23.2.1 [container.requirements.general]

Мое понимание этого: ЕслиT (в нашем случаеstd::pair<const int,std::unique_ptr<int>>) не являетсяCopyInsertable вX (в нашем случаеstd::unordered_map<int,std::unique_ptr<int>>), затемX u(a) а такжеX u=a не хорошо сформированы.

НаCopyInsertable

T являетсяCopyInsertable вX означает, что в дополнение кT являющийсяMoveInsertable вX, следующее выражение правильно сформировано:

allocator_traits<A>::construct(m, p, v)

и его оценка приводит к выполнению следующего постусловия:v не изменяется и эквивалентно*p.

Мое понимание этого: std::pair<const int,std::unique_ptr<int>> не являетсяCopyInsertableиз-за того, чтоstd::unique_ptr<int> не копируется:

Каждый объект типаU созданный изunique_ptr шаблон, указанный в этом подпункте [...], не являетсяCopyConstructible ниCopyAssignable.

§20.8.1 [unique.ptr]

И из-за того, что конструктор копированияstd::pair<const int,std::unique_ptr<int>> по умолчанию:

pair(const pair&) = default;

§20.3.2 [парная пара]

И из-за того, чтоstd::pair<const int,std::unique_ptr<int>> имеет член типаstd::unique_ptr<int>:

template <class T1, class T2> struct pair {

[...]

T2 second;

§20.3.2 [парная пара]

И из-за того, что конструкторы копий по умолчанию удаляются, когда это не так, что все члены типаCopyConstructible:

По умолчанию конструктор копирования / перемещения для классаX определяется как удаленный, если X имеет:

[...]

нестатический член данных типа классаM (или их массив), которые нельзя скопировать / переместить из-за разрешения перегрузки применительно кMСоответствующий конструктор приводит к [...] удаленной функции [...]

§12.8 [class.copy]

Наstd::is_copy_constructible

Для ссылочного типаTтот же результат, что иis_constructible<T,const T&>::value, иначеfalse.

§20.10.4.3 [meta.unary.prop]

Мое понимание / чтение этого: std::is_copy_constructible<std::unordered_map<int,std::unique_ptr<int>> такой же какstd::is_constructible<std::unordered_map<int,std::unique_ptr<int>,std::unordered_map<int,std::unique_ptr<int> &>.

Наstd::is_constructible

Учитывая следующую функцию прототипа:

template <class T> add_rvalue_reference_t<T> create() noexcept;

условие предиката для специализации шаблонаis_constructible<T, Args...> должны быть выполнены, если и только если следующее определение переменной будет правильно сформировано для некоторой изобретенной переменнойt:

T t(create<Args>()...);

§20.10.4.3 [meta.unary.prop]

Мое понимание этого: std::is_constructible<std::unordered_map<int,std::unique_ptr<int>>,std::unordered_map<int,std::unique_ptr<int> &> должно бытьstd::false_typeнеstd::true_type, посколькуX u(a) не хорошо сформирован.

Мой вопрос

Должен ли вышеуказанный код быть принят? Это ошибка GCC / libstdc ++ или в стандарте что-то отсутствует?

В настоящее время у меня нет доступа к Clang или MSVC ++, иначе я бы протестировал их.

Ответы на вопрос(1)

Ваш ответ на вопрос