https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654

Daniel Krügler <daniel.kruegler at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.kruegler@googlemail.
                   |                            |com

--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> ---
Here are two problems involved:

1) std::vector's copy constructor is not SFINAE-friendly and causes
std::is_copy_constructible to evaluate to true regradless of it's element type.
This is a QoI issue but not a violation of the requirements of the standard.

2) The more serious problem is that the intrinsic __is_trivially_constructible
is the actual cause of the non-silent response here. This can be demonstrated
by evaluating the statement

__is_trivially_constructible(std::vector<nocopy>, const std::vector<nocopy>&);

which results in the following compiler error:

//----------------------------
H:\Develop\Cpp\C++0x\ScratchBook\main.cpp||In function 'int main()':|
H:\Develop\Cpp\C++0x\ScratchBook\main.cpp|28|warning: statement has no effect
[-Wunused-value]|
c:\program files\develop\gcc\include\c++\8.0.0\bits\stl_construct.h||In
instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = nocopy;
_Args = {const nocopy&}]':|
c:\program
files\develop\gcc\include\c++\8.0.0\bits\stl_uninitialized.h|83|required from
'static _ForwardIterator
std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator =
__gnu_cxx::__normal_iterator<const nocopy*, std::vector<nocopy> >;
_ForwardIterator = nocopy*; bool _TrivialValueTypes = false]'|
c:\program
files\develop\gcc\include\c++\8.0.0\bits\stl_uninitialized.h|134|required from
'_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator,
_ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const
nocopy*, std::vector<nocopy> >; _ForwardIterator = nocopy*]'|
c:\program
files\develop\gcc\include\c++\8.0.0\bits\stl_uninitialized.h|289|required from
'_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator,
_ForwardIterator, std::allocator<_Tp>&) [with _InputIterator =
__gnu_cxx::__normal_iterator<const nocopy*, std::vector<nocopy> >;
_ForwardIterator = nocopy*; _Tp = nocopy]'|
c:\program files\develop\gcc\include\c++\8.0.0\bits\stl_vector.h|331|required
from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with
_Tp = nocopy; _Alloc = std::allocator<nocopy>]'|
H:\Develop\Cpp\C++0x\ScratchBook\main.cpp|28|required from here|
c:\program files\develop\gcc\include\c++\8.0.0\bits\stl_construct.h|75|error:
use of deleted function 'nocopy::nocopy(const nocopy&)'|
H:\Develop\Cpp\C++0x\ScratchBook\main.cpp|18|note: declared here|
||=== Build failed: 1 error(s), 7 warning(s) (0 minute(s), 0 second(s)) ===|
//----------------------------

Note that evaluating

std::is_copy_constructible<std::vector<nocopy>>

alone doesn't spit at the programmer, but happily instantiates.

The only clean choice is to fix the __is_trivially_constructible intrinsic.
Wrapping the current call of that intrinsic by expanding the current
std::is_trivially_copy_constructible definition as follows

  template<typename _Tp>
  struct __is_trivially_constructible_delayed
  : public integral_constant<bool,
                        __is_trivially_constructible(_Tp, const _Tp&)>
  { };

  template<typename _Tp>
  struct is_trivially_copy_constructible
  : public __and_<is_copy_constructible<_Tp>,
            __is_trivially_constructible_delayed<_Tp>>
  { };

wouldn't solve the problem, because due to the wrong positive result of
std::is_copy_constructible<std::vector<nocopy>> the protected
__is_trivially_constructible_delayed would still be instantiated.

Reply via email to