Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Perfect forwarding in C++03

4 views
Skip to first unread message

Andy Venikov

unread,
Nov 24, 2009, 11:21:32 AM11/24/09
to
I know that in C++0x implementing perfect forwarding will be a bliss
(what with the variadic templates and RVAL reference I could do anything
I wish and then some :-)

But barring the usage of C++0x, what are my options?

I read an old proposal by Peter Dimvov, Dave Abrahams and Howard Hinnant
that does a nice job describing some current options.
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

Has there emerged anything new since then?

Also, in my case it is actually OK to put a requirement on the caller to
do something extra in case when pass-by-nonconst-reference is desired.
Namely, when the caller wants to call a function signature that accepts
a non-const reference, the caller needs to use boost::ref().

Having that in mind, can I just use a const reference for everything?

I.e.

template <typename Functor, typename Prmr1>
<deductable return type> forward(Functor f, Prmr1 const & p1)
{
return f(p1);
}

template <typename Functor, typename Prmr1, typename Prmr2>
<deductable return type> forward(Functor f, Prmr1 const & p1,
Prmr2 const & p2)
{
return f(p1, p2);
}

//And so forth for 3, 4 , 5... arguments.

Then the caller could call forward() as-is for pass-by-value or
pass-by-const-reference parameters, but use boost::ref() to pass by
non-const reference.

The only problem that I can see is trying to pass a function as an argument.

Thanks,
Andy.

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

Kenshin

unread,
Nov 25, 2009, 9:21:23 AM11/25/09
to
On Nov 24, 7:21 pm, Andy Venikov <swojchelo...@gmail.com> wrote:
> I know that in C++0x implementing perfect forwarding will be a bliss
> (what with the variadic templates and RVAL reference I could do anything
> I wish and then some :-)
>
> But barring the usage of C++0x, what are my options?
>
> I read an old proposal by Peter Dimvov, Dave Abrahams and Howard Hinnant
> that does a nice job describing some current options.http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm

>
> Has there emerged anything new since then?
>
> Also, in my case it is actually OK to put a requirement on the caller to
> do something extra in case when pass-by-nonconst-reference is desired.
> Namely, when the caller wants to call a function signature that accepts
> a non-const reference, the caller needs to use boost::ref().
>
> Having that in mind, can I just use a const reference for everything?
>
> I.e.
>
> template <typename Functor, typename Prmr1>
> <deductable return type> forward(Functor f, Prmr1 const & p1)
> {
> return f(p1);
>
> }
>
> template <typename Functor, typename Prmr1, typename Prmr2>
> <deductable return type> forward(Functor f, Prmr1 const & p1,
> Prmr2 const & p2)
> {
> return f(p1, p2);
>
> }
>
> //And so forth for 3, 4 , 5... arguments.
>
> Then the caller could call forward() as-is for pass-by-value or
> pass-by-const-reference parameters, but use boost::ref() to pass by
> non-const reference.
>
> The only problem that I can see is trying to pass a function as an argument.
>
> Thanks,
> Andy.
>

AFAIK, boost::ref returns an implicit reference to an object passed by
value; it does not cast const away. Using boost::ref here will create
a "const reference_wrapper<Prmr1>(p1) &" object, & pass that on to
"f". If function "f" takes arguments by value or non-const ref, this
will not compile.

Andy Venikov

unread,
Nov 26, 2009, 1:07:14 AM11/26/09
to
Kenshin wrote:
<snip>

>> template <typename Functor, typename Prmr1>
>> <deductable return type> forward(Functor f, Prmr1 const & p1)
>> {
>> return f(p1);
>>
>> }
>>
>> template <typename Functor, typename Prmr1, typename Prmr2>
>> <deductable return type> forward(Functor f, Prmr1 const & p1,
>> Prmr2 const & p2)
>> {
>> return f(p1, p2);
>>
>> }
>>
>> //And so forth for 3, 4 , 5... arguments.
>>
>> Then the caller could call forward() as-is for pass-by-value or
>> pass-by-const-reference parameters, but use boost::ref() to pass by
>> non-const reference.
>>
>> The only problem that I can see is trying to pass a function as an argument.
>>
>> Thanks,
>> Andy.
>>
>
> AFAIK, boost::ref returns an implicit reference to an object passed by
> value; it does not cast const away. Using boost::ref here will create
> a "const reference_wrapper<Prmr1>(p1) &" object, & pass that on to
> "f". If function "f" takes arguments by value or non-const ref, this
> will not compile.


reference_wrapper<T> has a conversion operator that returns a non-const
reference.

operator T& () const;

Note the const qualifier.

That means that if the forwarding function's parameter is
reference_wrapper<T> const & and if f accepts T& then passing this
parameter as an argument to f has the desired effect of passing the
non-const reference to T.

Since, as I said before, the caller would only use boost::ref for
non-const ref parameters, I think this technique should work. I think
using boost::ref for pass-by-value should work too, but that's not required.

Thanks for your comment,
Andy.

Kenshin

unread,
Nov 26, 2009, 11:25:55 AM11/26/09
to

{ edits: quoted sig and banner removed. don't quote sigs or the banner. -mod }

Yes, teh belwo does run:

#include <iostream>

#include "boost/ref.hpp"


void func(int& i){

++i;

}

template <class Prmr1>
void forward(const Prmr1& p1)
{
func(p1);
}


int main(int argc, char** argv){

int x = 444;

std::cout << x << std::endl;

forward(boost::ref(x));

std::cout << x << std::endl;

return 0;

0 new messages