From: Luc Danton on
On 18/07/2010 00:27, SG wrote:
> Any user-defined constructor disables the implicit generation of a
> default constructor. So, that's maybe what you were thinking of.

Thanks for correcting me. That was indeed my idea.

>> This is obvious but if you forget it you might not notice it if the
>> perfectly-forwarded call is valid construct!
>
> I'm not following you.

I've had past problems where when copying a custom, tuple-like template class some_tuple<T>, I end up instead with some_tuple<some_tuple<T>>.
Obviously for most cases the compiler is going to complain that you're trying to stuff a some_tuple<T> into a T, and that's a Good Thing. Sometimes, it doesn't, typically when type-erasure is involved. Simplest example I can think of (but didn't happen to me) is boost::Any. More simply however I've had this bit me with std::function (where my tuple-like class had an operator()).

>> The obvious cure is adding the default copy constructor:
>
> I don't see why this is supposed to be necessary.
> [snip]
> As far as I can tell this follows from the overload resolution rules.

So the actual ill is that the variadic constructor will eat refs to non-const. Nothing ever happens to the copy constructor. Thanks for clearing that up.

>> [snip]
>
> I can think of two approaches to handle this situation.
>
> (1) Offer both copy constructors (one taking ref-to-const and another
> taking a ref-to-non-const)
>
> (2) Split the variadic contructor template into two templates: one
> handling a single argument and another handling two or more
> arguments. The first one would use SFINAE to disable the
> U=some_type& case.
>
>
> Cheers!
> SG

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]