From: Yechezkel Mett on
On Nov 18, 3:42 am, Boris Rasin <rasin.bo...(a)gmail.com> wrote:
> On Nov 17, 10:45 pm, Alberto Ganesh Barbati <AlbertoBarb...(a)libero.it>
> wrote:
> > 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.
>

Semi-tested code that I happened to have lying around:

template<class... T> struct emplacer_t;

template<class H, class... T> struct emplacer_t<H, T...>
{
emplacer_t(H&& head, T&&... tail)
: head(head), tail(tail...)
{}

H&& head;
emplacer_t<T...> tail;
};

template<> struct emplacer_t<> {};

template<class... T> emplacer_t<T...> emplace(T&&... t)
{
return emplacer_t<T...>(std::forward<T>(t)...);
}

template<class... Unpacked, Callable<auto, Unpacked&&...> F>
F::result_type
inline apply_args(emplacer_t<> e, F f, Unpacked&&... u)
{
return f(std::forward<Unpacked>(u)...);
}

template<class RestHead, class... RestTail, class... Unpacked,
Callable<auto, Unpacked&&..., RestHead&&, RestTail&&...> F>
F::result_type
inline apply_args(emplacer_t<RestHead, RestTail...> e, F f,
Unpacked&&... u)
{
return apply_args(emplacer_t<RestTail...>(e.tail), f,
std::forward<Unpacked>(u)..., std::forward<RestHead>(e.head));
}

To compile it under concept-gcc I had to remove std::Callable (which
means removing result_type) and std::forward.

Here the argument list is in a structure called emplace_t -- to unpack
std::tuple is slightly more difficult because there's no easy way to
get the tail, but it can be done.

Yechezkel Mett


--
[ 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 19, 11:29 pm, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:

> 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

Nice work, I am glad to see generic version, but wouldn't you agree
that my initial sample (at some point allowed by variadic templates
proposal - n1704) looks so much better:

template <typename ... Args>
struct store
{
store (Args ... args) : members (args) ... {}
void forward() { some_func (members ...); }
Args ... members;
};


--
[ 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 18, 8:43 pm, Alberto Ganesh Barbati <AlbertoBarb...(a)libero.it>
wrote:

> Using preprocessor metaprogramming it is not difficult to have N
> arbitrarily high. See, for
examplehttp://www.boost.org/doc/libs/1_37_0/libs/preprocessor/doc/index.html

The whole point of variatic templates is to avoid code like this.


--
[ 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 20 Nov., 22:45, Boris Rasin <rasin.bo...(a)gmail.com> wrote:
[..]
> Nice work, I am glad to see generic version, but wouldn't you agree
> that my initial sample (at some point allowed by variadic templates
> proposal - n1704) looks so much better:
>
> template <typename ... Args>
> struct store
> {
> store (Args ... args) : members (args) ... {}
> void forward() { some_func (members ...); }
> Args ... members;
> };

I agree that both syntax and implementation complexity
would be strongly reduced with what the authors of N1704
named "First-class parameter packs".

The two counter arguments mentioned in this paper, namely

a) "First-class parameter packs may be somewhat confusing to
users, because the distinction between a �packed� parameter
pack and an unpacked one becomes very important"

and

b) "First-class parameter packs introduce more complexity into
the implementation of variadic templates, because the compiler
must construct actual types and objects for each parameter pack"

do not apply IMO.

For me (a) is not valid, because the programmer has already to
be aware of the important semantic difference of an unpacked
variadic pack. And I would exclude argument (b) by simply
trying to fit this into the list of [temp.variadic]/4 with the
meaning
of an ordered list of member declarations such that

Args... members;

would have the meaning of

Arg[0] member0;
Arg[1] member1;
....

Doing this, there is no need for the compiler that Args... is
a special type by itself.

Basically we have realized that for base class lists as well,
see e.g. the example given in 12.6.2 [class.base.init]/11:

template<class... Mixins>
class X : public Mixins... {
public:
X(const Mixins&... mixins) : Mixins(mixins)... { }
};

So I see no more convincing arguments against this
additional use case.

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! ]

From: Larry Evans on
On 11/26/08 14:47, Daniel Kr�gler wrote:
[snip]
>
> Just to be sure: have you sent this contributions also to
> comp.lang.c++.mod? I think your reply is quite important!
>
>
Yes; however, I've not received any acknowledgment.
I think my newsreader (part of thunderbird) is still
giving me problems. Maybe you could just forward
this reply to the newsgroup to workaround my
newreader problems. However, I have cc'ed the
moderators directly, and if past experience is a
guide, this should work.

BTW, one advantage of

Args... members;

is that it could avoid the extra overhead of the recursive
tuple implementation found on page 4 of:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2080.pdf

That extra overhead was mentioned in post:

http://lists.boost.org/Archives/boost/2002/01/23881.php

-regards,
Larry


-Larry


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