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 ++, иначе я бы протестировал их.