Prev: ANN: Library dependency graphs tool status update and questions
Next: warning: ... has a field ... whose type uses the anonymous namespace
From: Boris Rasin on 17 Nov 2008 08:30 On Nov 17, 9:27 am, Mathias Gaunard <loufo...(a)gmail.com> wrote: > On 16 nov, 18:01, Boris Rasin <rasin.bo...(a)gmail.com> wrote: > > > Like I said, I want (perfect) forwarding at a later stage (see > > "forward" member function in my sample). And "tuple<Args...> members" > > wouldn't work. > > And how so? > tuple can be your own type if std::tuple somehow doesn't suit your > needs. If you think there is a way to implement later forwarding (the "forward" function in my sample) using tuple or anything else, why don't you provide an example? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Boris Rasin on 17 Nov 2008 08:32 On Nov 14, 1:31 am, Boris Rasin <rasin.bo...(a)gmail.com> wrote: > I am thinking about possible implementation for a class to store > arbitrary number of objects of arbitrary types, just like tuple<>, but > with support for later (perfect) forwarding. As far as I understand, > the code in the simplified example below is not supported by c++0x. If > so, can someone explain why support for this case is not included in c+ > +0x variadic templates? Is there an alternative implementation I am > missing? > > template <class ... Args> > class store > { > public: > > store (Args ... args) : members (args) ... {} > void forward() { some_func (members ...); } > > Args ... members; // Error: template parameter pack expansion not > supported in this context. Why not? > > }; As Larry Evans pointed out to me, this was supported in the initial variadic templates proposal (http://www.open-std.org/jtc1/sc22/wg21/ docs/papers/2004/n1704.pdf). Looks like it was dropped from a later edition (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/ n2080.pdf) and it is not in the current draft. It would be interesting to hear from someone who knows the reason for this removal, as it doesn't seem to be possible to implement generic later forwarding without this feature. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Boris Rasin on 17 Nov 2008 08:42 On Nov 17, 10:45 pm, Alberto Ganesh Barbati <AlbertoBarb...(a)libero.it> wrote: > Boris Rasin ha scritto: > > > > > On Nov 14, 6:09 pm, Mathias Gaunard <loufo...(a)gmail.com> wrote: > >> On 14 nov, 00:31, Boris Rasin <rasin.bo...(a)gmail.com> wrote: > > >>> template <class ... Args> > >>> class store > >>> { > >>> public: > >>> store (Args ... args) : members (args) ... {} > >>> void forward() { some_func (members ...); } > >>> Args ... members; // Error: template parameter pack expansion not > >>> supported in this context. Why not? > >> What could it do? > >> Try tuple<Args...> members; > > > Like I said, I want (perfect) forwarding at a later stage (see > > "forward" member function in my sample). And "tuple<Args...> members" > > wouldn't work. > > All you need is an helper function like this: > > template <class T, class... Args> > /* whatever */ invoke(T f, tuple<Args...>&& args); > > which calls f with the supplied arguments. It should not be too > difficult to make it a perfect forwarder. > > Ganesh Seeing that it should not be too difficult, would you mind actually showing how to call a function with any number of parameters given tuple<> object as parameter container (as in your sample)? No need to make it a perfect forwarding, just anything that would actually work. Thank you very much. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 18 Nov 2008 01:43 Boris Rasin ha scritto: > On Nov 17, 10:45 pm, Alberto Ganesh Barbati <AlbertoBarb...(a)libero.it> >> All you need is an helper function like this: >> >> template <class T, class... Args> >> /* whatever */ invoke(T f, tuple<Args...>&& args); >> >> which calls f with the supplied arguments. It should not be too >> difficult to make it a perfect forwarder. >> >> Ganesh > > Seeing that it should not be too difficult, would you mind actually > showing how to call a function with any number of parameters given > tuple<> object as parameter container (as in your sample)? No need to > make it a perfect forwarding, just anything that would actually work. You can't do that for an arbitrary number of parameters, due to the limitation of the pack expansion syntax you already noticed. However, it is definitely possible to do it the "old way", that is to provide several specializations for 1, 2, 3 up to N parameters some N. For example for N = 3: template <typename T, typename A0> /* some result_of or Callable<> expression here */ invoke(T&& f, tuple<A0>&& args) { return f(std::forward<A0>(get<0>(args))); } template <typename T, typename A0, typename A1> /* some result_of or Callable<> expression here */ invoke(T&& f, tuple<A0, A1>&& args) { return f( std::forward<A0>(get<0>(args)), std::forward<A1>(get<1>(args))); } template <typename T, typename A0, typename A1, typename A2> /* some result_of or Callable<> expression here */ invoke(T&& f, tuple<A0, A1, A2>&& args) { return f( std::forward<A0>(get<0>(args)), std::forward<A1>(get<1>(args)), std::forward<A2>(get<2>(args))); } Using preprocessor metaprogramming it is not difficult to have N arbitrarily high. See, for example http://www.boost.org/doc/libs/1_37_0/libs/preprocessor/doc/index.html HTH, Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 19 Nov 2008 04:29
On 18 Nov., 02:32, Boris Rasin <rasin.bo...(a)gmail.com> wrote: > On Nov 14, 1:31 am, Boris Rasin <rasin.bo...(a)gmail.com> wrote: > > I am thinking about possible implementation for a class to store > > arbitrary number of objects of arbitrary types, just like tuple<>, but > > with support for later (perfect) forwarding. As far as I understand, > > the code in the simplified example below is not supported by c++0x. If > > so, can someone explain why support for this case is not included in c+ > > +0x variadic templates? Is there an alternative implementation I am > > missing? > > > template <class ... Args> > > class store > > { > > public: > > > store (Args ... args) : members (args) ... {} > > void forward() { some_func (members ...); } > > > Args ... members; // Error: template parameter pack expansion not > > supported in this context. Why not? > > > }; > > As Larry Evans pointed out to me, this was supported in the initial > variadic templates proposal (http://www.open-std.org/jtc1/sc22/wg21/ > docs/papers/2004/n1704.pdf). Looks like it was dropped from a later > edition (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/ > n2080.pdf) and it is not in the current draft. It would be interesting > to hear from someone who knows the reason for this removal, as it > doesn't seem to be possible to implement generic later forwarding > without this feature. Maybe I'm too stupid to recognize the traps which you obviously have in your mind. The following code bases on the approach described in N2080 and compiles well on ConceptGcc (It is more or less variadic version of Alberto Barbati's proposal): #include <concepts> #include <cstddef> #include <tuple> #include <utility> // <ext> (because ConceptGcc is not aware of the most // recent standard draft) namespace std { auto concept IdentityOf<typename T> { typename type = T; requires SameType<type, T>; } template <IdentityOf T> inline T&& forward(IdentityOf<T>::type&& t) { return t; } } //</ext> template<std::size_t...> struct index_tuple{}; template<std::size_t I, typename IndexTuple, typename... Types> struct make_indices_impl; template<std::size_t I, std::size_t... Indices, typename T, typename... Types> struct make_indices_impl<I, index_tuple<Indices...>, T, Types...> { typedef typename make_indices_impl<I + 1, index_tuple<Indices..., I>, Types...>::type type; }; template<std::size_t I, std::size_t... Indices> struct make_indices_impl<I, index_tuple<Indices...> > { typedef index_tuple<Indices...> type; }; template<typename... Types> struct make_indices : make_indices_impl<0, index_tuple<>, Types...> { }; template <class... Args> void some_func(Args&&...){} template <class... Args> class store { public: store(Args... args) : members(args...) {} void forward() { typedef typename make_indices<Args...>::type Indices; return forward0(Indices(), members); } private: template <std::size_t... Indices> static void forward0(index_tuple<Indices...>, std::tuple<Args...>&& args) { some_func(std::forward<Args>(std::get<Indices>(args))...); } std::tuple<Args...> members; }; int main() { store<int, bool, double>(42, true, 1.2).forward(); } HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |