g++ --version
yields:
g++.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This i
There are two problems in your analysis.
First, violating a Requires clause causes undefined behavior (§17.6.4.11 [res.on.required]):
Violation of the preconditions specified in a function’s Requires: paragraph results in undefined behavior unless the function’s Throws: paragraph specifies throwing an exception when the precondition is violated.
Which means that the library can do anything it wants if you try to copy construct an unordered_map
with a non-CopyInsertable element. It doesn't necessarily lead to the program being ill-formed (although it probably will, somewhere deep inside the copy constructor's implementation).
Second, the testing performed by the is_constructible
trait is limited to the immediate context (§20.10.4.3 [meta.unary.prop]/p7, emphasis added):
Access checking is performed as if in a context unrelated to
T
and any of theArgs
. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. —end note ]
In other words, this basically just considers if there's a matching, accessible, and non-deleted constructor signature, not if instantiating the constructor will result in well-formed code.
The standard would have to specify the copy constructor of containers with something along the lines of "this constructor shall not participate in overload resolution if T
is not CopyInsertable into X
" to guarantee that the is_copy_constructible
trait behaves the way you want it to. There is no such specification in the standard.
As Marc Glisse wrote in the comments, while this isn't mandated by the standard, it can be considered a quality of implementation issue, so a bug report would be reasonable.
Edit: It occurred to me that a requirement to remove the copy constructor from overload resolution for non-CopyInsertable
elements is probably not implementable, since that property is specified in terms of a call to allocator_traits<A>::construct(m, p, v)
being well-formed and having the required semantics. I do not believe SFINAE could determine the well-formedness of the body of the call to allocator_traits<A>::construct()
.