Hey all, I've just attempted to move my project from g++ v4.6.3 to
v4.7.1 and hit an issue when using move semantics.
I have a templated class LockGuard that is move-constructable and not
copyable. This is accomplished (in the conventional C++98 way) by making
the copy constructor "private". The code creates an instance of
std::pair<..., LockGuard<...>> and returns it to the caller.
The code compiles and runs on g++ 4.6.3 and VS2010/sp1, yet g++ 4.7.1
emits a bunch of errors (below). The point, as far as I can tell, is
that it wants to call the copy constructor which is private. I can fix
the issue by explicitly removing the copy constructor:
LockGuard(const LockGuard &) = delete;
Could someone clarify if this behavior is conforming to the standard?
Normally I would not worry about such a thing, but VS2010 does not
understand "= delete" specs and the behavior appears to be a breaking
change w.r.t. copy constructor invocations... (well, breaking is too
strong a word as move constructors and rvalue references are new, but I
am sure you see what I mean)
I'd appreciate any insight into the front-end and library design.
Thanks in advance,
Oleg.
------------------------------------------------------------------------
In file included from ../../../core/libs/base/iocp.h:4:0,
from ../../../core/libs/base/buff.h:15,
from ../../../core/tests/base_test/base_test.cpp:3:
/usr/include/c++/4.7/type_traits: In substitution of ‘template<class
_From1, class _To1> static decltype
((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one()))
std::__is_convertible_helper<_From, _To, false>::__test(int) [with
_From1 = _From1; _To1 = _To1; _From = const
base::LockGuard<base::Lock>&; _To = base::LockGuard<base::Lock>] [with
_From1 = const base::LockGuard<base::Lock>&; _To1 =
base::LockGuard<base::Lock>]’:
/usr/include/c++/4.7/type_traits:1258:70: required from ‘constexpr
const bool std::__is_convertible_helper<const
base::LockGuard<base::Lock>&, base::LockGuard<base::Lock>, false>::value’
/usr/include/c++/4.7/type_traits:1263:12: required from ‘struct
std::is_convertible<const base::LockGuard<base::Lock>&,
base::LockGuard<base::Lock> >’
/usr/include/c++/4.7/type_traits:116:12: required from ‘struct
std::__and_<std::is_convertible<const
std::shared_ptr<{anonymous}::State>&,
std::shared_ptr<{anonymous}::State> >, std::is_convertible<const
base::LockGuard<base::Lock>&, base::LockGuard<base::Lock> > >’
/usr/include/c++/4.7/bits/stl_pair.h:113:38: required from ‘constexpr
std::pair<typename std::__decay_and_strip<_T1>::__type, typename
std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with
_T1 = std::shared_ptr<{anonymous}::State>&; _T2 =
base::LockGuard<base::Lock>; typename
std::__decay_and_strip<_T2>::__type = base::LockGuard<base::Lock>;
typename std::__decay_and_strip<_T1>::__type =
std::shared_ptr<{anonymous}::State>]’
../../../core/tests/base_test/base_test.cpp:1282:70: required from here
../../../core/libs/base/synchronisation.h:113:9: error:
‘base::LockGuard<Type>::LockGuard(const base::LockGuard<Type>&) [with
Type = base::Lock; base::LockGuard<Type> = base::LockGuard<base::Lock>]’
is private