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
TCopyInsertableв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 [pairs.pair]
И из-за того, что std::pair<const int,std::unique_ptr<int>> имеет член типа std::unique_ptr<int>:
template <class T1, class T2> struct pair {[...]
T2 second;§20.3.2 [pairs.pair]
И из-за того, что дефолтные конструкторы копий удаляются, когда это не так, что все члены типа CopyConstructible:
По умолчанию конструктор copy/move для класса
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/libstdС++, или есть что-то в стандарте, который мне не хватает?
В настоящее время у меня нет доступа к Clang или MSVС++, иначе я бы тестировал их.
