C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Two Questions about R-value reference( N2118)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Sun Nov 26, 2006 11:59 pm    Post subject: Two Questions about R-value reference( N2118) Reply with quote



A careful reading of N2118 revealed that the modification of 7.1.3(i.e.
the typedef specifier) and that of 14.3.1(i.e. template type arguments)
essentially articulated the same rule, which, if stated simply, is "the
attempt to create a lvalue-reference(whether cv qualified or not) to
some reference-type RT(RT shall be a typedef-name or template type
parameter) essentially modifys the reference part of the type RT into
lvalue-reference and keeping other aspects intact; while the attempt to
create a rvalue-reference(whether cv qualified or not) to such RT
leaves RT as is. So, should the rule for 14.3.1 be defined in terms of
that of 7.1.3, or just refer to that of 7.1.3?

P.S. Should the above wording be added as a note in order to clarify
this special-made rule? ( coz I think the asymmetric-ness of the rules
for l-value reference and r-value reference will probably confuse the
novices.)
Also, it'd be the best if this wording include a little motivation
description of the rule, which of course is for perfect forwarding,
that'll use several lines of words but will worth a lot:)

Another question, consider:

template<typename T>
void f(T&&);
template<typeanme T>
void f(T&);

int i;
f(i); // call which?

Should the partial ordering rule explicitly deal with this situation?

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Pedro Lamarão
Guest





PostPosted: Mon Nov 27, 2006 3:49 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote



On 26 nov, 21:59, pon...@gmail.com wrote:

Quote:
Another question, consider:

template<typename T
void f(T&&);
template<typeanme T
void f(T&);

int i;
f(i); // call which?

i is an l-value, so it will be bound to the second overload.
Moving must be explicitly cast in this case:

f(static_cast<int&&>(i));

or like this, if it makes it into de library:

f(std::move(i));

--
Pedro Lamarão


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Howard Hinnant
Guest





PostPosted: Mon Nov 27, 2006 9:42 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote



In article <1164526625.677496.66940 (AT) l39g2000cwd (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

Quote:
template<typename T
void f(T&&);
template<typeanme T
void f(T&);

int i;
f(i); // call which?

Should the partial ordering rule explicitly deal with this situation?

The current language sees this as ambiguous between:

f<int>(int&);
f<int&>(int&);

I haven't run across motivation to disambiguate these. Indeed the
current rules were specifically written such that the T&& signature
could handle the intentions of f(T&) (i.e. perfect forwarding).

If one does want to disambiguate these (treat lvalues and rvalues
differently) then tag dispatching could be used (just as an example):

template <class T>
void
f_imp(T&, std::true_type);

template <class T>
void
f_imp(T&&, std::false_type);

template<typename T>
inline
void
f(T&& t)
{
return f_imp(std::forward<T>(t),
std::integral_constant<bool,
std::is_lvalue_reference<T>::value>());
}

However after "moving" the std::lib and large parts of tr1, I've yet to
run across a use case for the above code. More commonly f(T&&) is
forwarding to a function where template argument deduction is not
applicable (either non-template code or the template parameter is
already elsewhere specified). std::pair is a good example of this:

template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;

T1 first;
T2 second;

template <class U, class V> pair(U&& x, V&& y)
: first(std::forward<U>(x)),
second(std::forward<V>(y)) {}

...
};

Here you do want to treat lvalue and rvalue U's differently, but the
code for actually doing that is (potentially) in T1's overloaded
constructor set. At the pair level one can use identical source code
for both lvalue and rvalue U's. So there is no overloading pair(U&,V&).

-Howard

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Tue Nov 28, 2006 5:10 am    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

Howard Hinnant wrote:
Quote:
In article <1164526625.677496.66940 (AT) l39g2000cwd (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

template<typename T
void f(T&&);
template<typeanme T
void f(T&);

int i;
f(i); // call which?

Should the partial ordering rule explicitly deal with this situation?

The current language sees this as ambiguous between:

f<int>(int&);
f<int&>(int&);

It seems to me that the overload resolution should choose f(T&) since

it's obviously the intention.

Quote:
I haven't run across motivation to disambiguate these. Indeed the
current rules were specifically written such that the T&& signature
could handle the intentions of f(T&) (i.e. perfect forwarding).

If one does want to disambiguate these (treat lvalues and rvalues
differently) then tag dispatching could be used (just as an example):


That's good observation:-)

Quote:
template <class T
void
f_imp(T&, std::true_type);

template <class T
void
f_imp(T&&, std::false_type);

template<typename T
inline
void
f(T&& t)
{
return f_imp(std::forward<T>(t),
std::integral_constant<bool,
std::is_lvalue_reference<T>::value>());
}

Again, good example.
However, I thinks the partial ordering rule should include the cases
where T&& is involved, in one way or another, just like the way it did
to T&/T const&.
After all, the bias to neither side when choosing between f(T&) and
f(T&&) is counter-intuitive to say the least.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Joe Gottman
Guest





PostPosted: Tue Nov 28, 2006 10:10 am    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

[Repost]
"Howard Hinnant" <howard.hinnant (AT) gmail (DOT) com> wrote in message
news:howard.hinnant-E36D06.08522527112006@syrcnyrdrs-03-ge0.nyroc.rr.com...
Quote:
In article <1164526625.677496.66940 (AT) l39g2000cwd (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

template<typename T
void f(T&&);
template<typeanme T
void f(T&);

int i;
f(i); // call which?

Should the partial ordering rule explicitly deal with this situation?

The current language sees this as ambiguous between:

f<int>(int&);
f<int&>(int&);

I haven't run across motivation to disambiguate these. Indeed the
current rules were specifically written such that the T&& signature
could handle the intentions of f(T&) (i.e. perfect forwarding).

How about std::remove_reference?

template <typename T> struct remove_reference
{
typedef T type;
};

template <typename T>
struct remove_reference<T &>
{
typedef T type;
};

template <typename T>
struct remove_reference<T &&>
{
typedef T type;
};


Joe Gottman

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Tue Nov 28, 2006 3:42 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

"Joe Gottman" wrote:
Quote:
How about std::remove_reference?

template <typename T> struct remove_reference
{
typedef T type;
};

template <typename T
struct remove_reference<T &
{
typedef T type;
};

template <typename T
struct remove_reference<T &&
{
typedef T type;
};

Great example! Since the partial ordering of class template partial
specializations is defined in terms of that of function templates,
there seems to be a problem.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Peter Dimov
Guest





PostPosted: Tue Nov 28, 2006 5:20 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

"Joe Gottman" wrote:
Quote:
[Repost]
"Howard Hinnant" <howard.hinnant (AT) gmail (DOT) com> wrote in message
news:howard.hinnant-E36D06.08522527112006@syrcnyrdrs-03-ge0.nyroc.rr.com...
In article <1164526625.677496.66940 (AT) l39g2000cwd (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

template<typename T
void f(T&&);
template<typeanme T
void f(T&);

int i;
f(i); // call which?

Should the partial ordering rule explicitly deal with this situation?

The current language sees this as ambiguous between:

f<int>(int&);
f<int&>(int&);

I haven't run across motivation to disambiguate these. Indeed the
current rules were specifically written such that the T&& signature
could handle the intentions of f(T&) (i.e. perfect forwarding).

How about std::remove_reference?

template <typename T> struct remove_reference
{
typedef T type;
};

template <typename T
struct remove_reference<T &
{
typedef T type;
};

template <typename T
struct remove_reference<T &&
{
typedef T type;
};

There is no problem with remove reference since a type can never be
both T& and T&&. The original ambiguity exists because in the T&& case,
T is deduced as int&, and because of the reference collapsing rule, T&&
is also int&. int & && is not a type, and neither is int & &, they
"normalize themselves" to int &.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Howard Hinnant
Guest





PostPosted: Wed Nov 29, 2006 3:56 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

In article <1164707130.301323.251100 (AT) j72g2000cwa (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

Quote:
"Joe Gottman" wrote:
How about std::remove_reference?

template <typename T> struct remove_reference
{
typedef T type;
};

template <typename T
struct remove_reference<T &
{
typedef T type;
};

template <typename T
struct remove_reference<T &&
{
typedef T type;
};

Great example! Since the partial ordering of class template partial
specializations is defined in terms of that of function templates,
there seems to be a problem.

Yes, I agree, excellent example. It sent me scurrying back to the CWG
for expert advise on this one. James Widman was kind enough to explain
things to me, and I'll try not to muddle his explanation too much.

remove_reference works as Joe shows because in transforming the partial
specialization into a function signature for the template type deduction
process we use:

template <typename T> void f(remove_reference<T&>);
template <typename T> void f(remove_reference<T&&>);

with an argument call like:

f(remove_reference<int&>());

I.e. there is no opportunity to apply 14.3.1p4 or 14.8.2.1p3.

(and fwiw, this behavior is consistent with current compiler prototypes)

-Howard

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Howard Hinnant
Guest





PostPosted: Wed Nov 29, 2006 3:57 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

In article <1164687428.748487.130240 (AT) l12g2000cwl (DOT) googlegroups.com>,
pongba (AT) gmail (DOT) com wrote:

Quote:
However, I thinks the partial ordering rule should include the cases
where T&& is involved, in one way or another, just like the way it did
to T&/T const&.
After all, the bias to neither side when choosing between f(T&) and
f(T&&) is counter-intuitive to say the least.

This is quite analogous to our current situation with:

template <class T> void f(T&);
template <class T> void f(T);

struct A {};

const A g();

int main()
{
f(g());
}

ambiguous;

f<A>(A)
f<const A>(const A&)

Perhaps we do want to tackle ambiguities such as these. But if so, I
see this as a separate issue from just the rvalue reference. It needs
to be motivated on its own merits and look across all similar
ambiguities.

-Howard

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Wed Nov 29, 2006 4:02 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

Peter Dimov wrote:
Quote:
There is no problem with remove reference since a type can never be
both T& and T&&. The original ambiguity exists because in the T&& case,
T is deduced as int&, and because of the reference collapsing rule, T&&
is also int&. int & && is not a type, and neither is int & &, they
"normalize themselves" to int &.

I don't think so(but maybe I misunderstood your point, feel free to
correct me).
The reason this example is ill-formed is that template type deduction
of class templates is defined in terms of that of function templates.
When we write remove_reference<int&>, an attempt is made to deduce T
from comparing T&(the P) to int&(the A), which sure will succeed, but
then another attempt is made to deduce T from comparing T&&(the P) to
int&(the A), and this will succeed too, since N2118 said that when
deduce T for a function template like f(T&&), the call argument type is
A& instead of A, which clearly indicates a comparation between T&& and
A&(here A is the *actual* non-reference-type of the call argument).

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Peter Dimov
Guest





PostPosted: Wed Nov 29, 2006 5:26 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

pongba (AT) gmail (DOT) com wrote:
Quote:
Peter Dimov wrote:
There is no problem with remove reference since a type can never be
both T& and T&&. The original ambiguity exists because in the T&& case,
T is deduced as int&, and because of the reference collapsing rule, T&&
is also int&. int & && is not a type, and neither is int & &, they
"normalize themselves" to int &.

I don't think so(but maybe I misunderstood your point, feel free to
correct me).
The reason this example is ill-formed is that template type deduction
of class templates is defined in terms of that of function templates.
When we write remove_reference<int&>, an attempt is made to deduce T
from comparing T&(the P) to int&(the A), which sure will succeed, but
then another attempt is made to deduce T from comparing T&&(the P) to
int&(the A), and this will succeed too, since N2118 said that when
deduce T for a function template like f(T&&), the call argument type is
A& instead of A, which clearly indicates a comparation between T&& and
A&(here A is the *actual* non-reference-type of the call argument).

If it worked this way, remove_reference<int> would match both
specializations, since both T& and T&& can be deduced from int in the
context of a function template taking T& and T&&. Intuitively, in this
case the deduction operates on the types, not on function arguments,
and must yield an exact match, without taking into account the special
T & && case that only applies to a limited subset of function calls.
Formally, I'm having trouble identifying the text that says so, though.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Thu Nov 30, 2006 4:22 pm    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

Peter Dimov wrote:
Quote:
If it worked this way, remove_reference<int> would match both
specializations, since both T& and T&& can be deduced from int in the
context of a function template taking T& and T&&. Intuitively, in this

Actually, the way template argument deduction works in cases of class
templates *is* a bit different from that of function templates.
For function templates, if P is of reference type, then the referenced
type is used instead of P for deduction, while for class templates, the
P, whether is a reference type or not, stays the same.
For example:

template<typename T>
void f(T&);

int i;
f(i); // here, P is T and A is int; deduction successful, with P
deduced as int.

but

template<typename T>
class C;

template<typename T>
class C<T&>{};

C<int> c; // the deduction for C<T&> will never succeed, 'cause P is
T&(i.e. the exact type).

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Peter Dimov
Guest





PostPosted: Fri Dec 01, 2006 12:50 am    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

pongba (AT) gmail (DOT) com wrote:
Quote:
Peter Dimov wrote:
If it worked this way, remove_reference<int> would match both
specializations, since both T& and T&& can be deduced from int in the
context of a function template taking T& and T&&. Intuitively, in this

Actually, the way template argument deduction works in cases of class
templates *is* a bit different from that of function templates.
For function templates, if P is of reference type, then the referenced
type is used instead of P for deduction, while for class templates, the
P, whether is a reference type or not, stays the same.

Right. Disregard my other post. N2118 14.8.2.1/3 works by discarding
the && off P and replacing A with A&. So if P is T&&, T is deduced as
A& and P becomes A& && == A&. But this doesn't mean that T&& can be
deduced from A&, so it seems that the remove_reference example is fine;
only one of the two specializations matches.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Peter Dimov
Guest





PostPosted: Fri Dec 01, 2006 5:47 am    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

pongba (AT) gmail (DOT) com wrote:
Quote:
Peter Dimov wrote:
If it worked this way, remove_reference<int> would match both
specializations, since both T& and T&& can be deduced from int in the
context of a function template taking T& and T&&. Intuitively, in this

Actually, the way template argument deduction works in cases of class
templates *is* a bit different from that of function templates.
For function templates, if P is of reference type, then the referenced
type is used instead of P for deduction, while for class templates, the
P, whether is a reference type or not, stays the same.

Yes, you are right, the current wording in N2118 14.8.2.1/3 does imply
that the type P == T&& is deducible from A& with T == A&. This would
make the partial specialization of remove_reference<T&&> match A&,
something that we don't want. I'm not sure what is the best way of
fixing it.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Guest






PostPosted: Fri Dec 01, 2006 6:03 am    Post subject: Re: Two Questions about R-value reference( N2118) Reply with quote

On Dec 1, 8:50 am, "Peter Dimov" <pdi...@gmail.com> wrote:
Quote:
Right. Disregard my other post. N2118 14.8.2.1/3 works by discarding
the && off P and replacing A with A&. So if P is T&&, T is deduced as
A& and P becomes A& && == A&. But this doesn't mean that T&& can be
deduced from A&, so it seems that the remove_reference example is fine;
only one of the two specializations matches.

Did I just lift a rock only to drop it on my own feet? I think so :-)

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.