From: Boris Rasin on
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
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
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
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
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! ]