From: bf on
Suppose I need a template that encapsulates an object, and I need the
ability to construct the template instantiations in all the ways that
the encapsulated object can be constructed. A possible construction
may be:

template <typename T>
class wrapped
{
public:
wrapped() {}
template <typename U>
wrapped(U&& u) : t(std::forward<U>(u) {}
private:
T t;
};

Unfortunately it fails if T isn't default constructible. A possible
solution can be made by defaulting the template parameter, instead of
an explicit default constructor.

template <typename T>
class wrapped
{
public:
template <typename U = T>
wrapped(U&& u = U()) : t(std::forward<U>(u) {}
private:
T t;
};

This allows default construction if T supports it, so logically it
works. In my experiments with g++, however, I see that the defaulted
value isn't optimized away. The move constructor for T is presumably
cheap, so it's probably not the end of the world, but it's
unnecessary. QOI detail, or behaviour mandated by proposed standard
wording?

I think a solution can be made with a variadic template constructor,
which also nicely takes care of multi-parameter constructors, but I
fail to figure out how to do a std::forward<U...>(u...). Suggestions?
_
/Bjorn

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

From: Larry Evans on
On Jul 14, 10:48 am, bf <bjor...(a)fahller.se> wrote:
[snip]
> I think a solution can be made with a variadic template constructor,
> which also nicely takes care of multi-parameter constructors, but I
> fail to figure out how to do a std::forward<U...>(u...). Suggestions?

You might try:

t( std::forward<U>(u)... )




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

From: Anthony Williams on
bf <bjorn_g(a)fahller.se> writes:

> Unfortunately it fails if T isn't default constructible. A possible
> solution can be made by defaulting the template parameter, instead of
> an explicit default constructor.
>
> template <typename T>
> class wrapped
> {
> public:
> template <typename U = T>
> wrapped(U&& u = U()) : t(std::forward<U>(u) {}
> private:
> T t;
> };

That will move-construct the member from a default-constructed
temporary.

> I think a solution can be made with a variadic template constructor,
> which also nicely takes care of multi-parameter constructors, but I
> fail to figure out how to do a std::forward<U...>(u...). Suggestions?

template<typename ... Args>
wrapped(Args&& ... args):
t(std::forward<Args>(args)...){}

Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++0x thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

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

From: Andy Venikov on
bf wrote:
<snip>
> I think a solution can be made with a variadic template constructor,
> which also nicely takes care of multi-parameter constructors, but I
> fail to figure out how to do a std::forward<U...>(u...). Suggestions?

....
template <typename ... Prms>
wrapped(Prms && ... prms) : t(std::forward<Prms>(prms)...)
{
}
....


> _
> /Bjorn
>

Andy.

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

From: Yechezkel Mett on
On Jul 14, 6:48 pm, bf <bjor...(a)fahller.se> wrote:
> Suppose I need a template that encapsulates an object, and I need the
> ability to construct the template instantiations in all the ways that
> the encapsulated object can be constructed.
....
> I think a solution can be made with a variadic template constructor,
> which also nicely takes care of multi-parameter constructors, but I
> fail to figure out how to do a std::forward<U...>(u...). Suggestions?


template <typename T>
class wrapped
{
public:
template <typename... U>
wrapped(U&&... u) : t(std::forward<U>(u)...) {}
private:
T t;
};

In

std::forward<U>(u)...

the ellipsis applies to the whole pattern "std::forward<U>(u)" which
can contain more than one parameter pack so long as all the parameter
packs have the same number of elements.

Yechezkel Mett


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