This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Weird (unintuitive?) behavior of std::tuple


--- On Sat, 30/10/10, Paolo Carlini <pcarlini@gmail.com> wrote:

> 
> > Isn't it just that default copy constructors are
> called making copies of
> > objects so destructors are called twice: once for
> "original" object and
> > once for it's copy?
> 
> Indeed. But this is the right reply for a message properly
> sent to gcc-help ;)
> 

Indeed, the behavior of pair is identical (and, as such, counter-
intuitive). pair<B, C> xx(B(), C()) won't invoke the constructors at all,
just like tuple (but will invoke the non-default ones, if those were
specified). pair or tuple declared without initialization arguments will
invoke default constructors as expected.

I posted the question here because I was investigating Jonathan's
suggestion that tuple can be used as a storage container inside a
shared_ptr. When the tuple is constructed in-place with general user
object (constructor arguments being passed through variadic template
constructor) evil stuff happens, due to the behavior described above.
It seems, I have to revert to using alloc_hider style helper classes for
now, because I can't make tuple work correctly.

In my original usage case below, runtime errors will emerge for a wide
variety of user specified _Tp types. This means, that either tuple/pair
as currently implemented are unfit for such usage (and this should be
documented somehow) or the implementation should be considered buggy.

template<typename _Tp>
struct ref_count_val
{

	template<typename... _Args>
	ref_count_val(ref_count<_Tp> *__ref, _Args&&... __args)
	: _M_ref(__ref), _M_v(std::forward<_Args>(__args)...)
	{}

	ref_count<_Tp> *_M_ref;
	_Tp             _M_v;
};

....

template<typename _Tp, typename _Alloc>
struct ref_count_a
{

	template<typename... _Args>
	ref_count_a(_Alloc __a, _Args&&... __args)
	:_M_valplus(ref_count_val<_Tp>(this, std::forward<_Args>(__args)...),
		    std::forward<_Alloc>(__a))
	{}

	std::tuple<ref_count_val<_Tp>, _Alloc> _M_valplus;
};





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]