Prev: Current time based on a timezone?
Next: Distinguish between pointers created with 'new' and created with references.
From: bf on 14 Jul 2010 00:48 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 14 Jul 2010 21:02 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 14 Jul 2010 21:08 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 15 Jul 2010 00:00 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 15 Jul 2010 08:47
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! ] |