472,350 Members | 1,666 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,350 software developers and data experts.

[c++0x] name deduction in overloading with rvalue references

Take the following snip (pretend A its a std::pair if you wish ;) )

template <class T1,class T2>
struct A {
A(A const&){cout<<"A(const&) ";}
A(A&&){cout<<"A(A&&) ";}
A(T1 const&, T2 const&){cout<<"A(T1,T2) ";}

template<class U1, class U2>
A(A<U1,U2&&) {cout<<"A(A<U1,U2>&&) ";}
template<class U, class... Args>
A(U&&,Args&&...){cout<<"A(U&&,Args&&...) ";}
};

int main(){
A<int,inta(1,1);
A<int,intb(a);
}

The output (gcc 4.3.0 20070824 with -std=c++0x) is:
A(U&&,Args&&...) A(U&&,Args&&...)

If I was to guess I would have thought:
A(T1,T2) A(const&)

So, the literal 1's are rvalues of type int&& I guess. So when the
params are deduced for the templated ctor with the variadic parameter,
I'm guessing U = int, Args... = int. Since 1 is an rvalue, A(int&&,
int&&) is the best match.

Ok. The next one, 'a' is an Lvalue of type A<int,int>. U then is
deduced to type A<int,int>& (N2639 14.8.2.1.3 I guess). I take it the
&& is dropped but I'm not sure how during the deduction process. I
guess it looks at parameter type U, see's that the argument is type
U&& but the REAL argument type is an lvalue so it converts the entire
argument type to an lvalue reference (unlike the first case where
int&& is the argument type, the real argument type is rvalue of type
int, so int&& is valid).

So, I go and add remove_reference<>'s to the parameter types (U and
Args). Now, in the first case A(T1,T2) is picked. I'd take a stab and
say that in "remove_reference<U>::type &&", the remove_reference is
applied AFTER the argument type is deduced to be int&& ? So the
argument type is... int? And the constant lvalue reference is picked
over an lvalue of type int when the actual argument type is an rvalue
int?

My head spins when I try to figure this stuff out so I wouldn't mind
if someone shed some light on the deduction process in the two cases
(that is, with and without remove_reference).

Much appreciated,
Chris

Aug 24 '07 #1
1 1635
In article <11**********************@x35g2000prf.googlegroups .com>,
Chris Fairles <ch***********@gmail.comwrote:
Take the following snip (pretend A its a std::pair if you wish ;) )

template <class T1,class T2>
struct A {
A(A const&){cout<<"A(const&) ";}
A(A&&){cout<<"A(A&&) ";}
A(T1 const&, T2 const&){cout<<"A(T1,T2) ";}

template<class U1, class U2>
A(A<U1,U2&&) {cout<<"A(A<U1,U2>&&) ";}
template<class U, class... Args>
A(U&&,Args&&...){cout<<"A(U&&,Args&&...) ";}
};

int main(){
A<int,inta(1,1);
A<int,intb(a);
}

The output (gcc 4.3.0 20070824 with -std=c++0x) is:
A(U&&,Args&&...) A(U&&,Args&&...)

If I was to guess I would have thought:
A(T1,T2) A(const&)

So, the literal 1's are rvalues of type int&& I guess. So when the
params are deduced for the templated ctor with the variadic parameter,
I'm guessing U = int, Args... = int. Since 1 is an rvalue, A(int&&,
int&&) is the best match.

Ok. The next one, 'a' is an Lvalue of type A<int,int>. U then is
deduced to type A<int,int>& (N2639 14.8.2.1.3 I guess). I take it the
&& is dropped but I'm not sure how during the deduction process. I
guess it looks at parameter type U, see's that the argument is type
U&& but the REAL argument type is an lvalue so it converts the entire
argument type to an lvalue reference (unlike the first case where
int&& is the argument type, the real argument type is rvalue of type
int, so int&& is valid).

So, I go and add remove_reference<>'s to the parameter types (U and
Args). Now, in the first case A(T1,T2) is picked. I'd take a stab and
say that in "remove_reference<U>::type &&", the remove_reference is
applied AFTER the argument type is deduced to be int&& ? So the
argument type is... int? And the constant lvalue reference is picked
over an lvalue of type int when the actual argument type is an rvalue
int?

My head spins when I try to figure this stuff out so I wouldn't mind
if someone shed some light on the deduction process in the two cases
(that is, with and without remove_reference).
Catching up on my newsgroup reading...

A<int,inta(1,1);

binds to:

A(U&&,Args&&...){cout<<"A(U&&,Args&&...) ";}

with U == int and Args == int. This is a better match than:

A(T1 const&, T2 const&){cout<<"A(T1,T2) ";}

because of the conversion to const int in each of the arguments. Note
that int does not get converted to type int&&. The '1's are just int.
It is because they are not const lvalues that is the deal killer.

Very similar story with :

A<int,intb(a);

Because 'a' is non-const it prefers the A(U&&,Args&&...) constructor
with U == A<int, int>&, and Args = {}. When template deduction happens
against U&&, if the argument A bound is an lvalue, U is deduced as A&,
not A. This makes perfect forwarding work.

The way this should be programmed in C++0X is:

template<class U, class... Args>
requires Constructible<T1, U&&&& Constructible<T2, Args&&...>
A(U&&,Args&&...){cout<<"A(U&&,Args&&...) ";}

I believe the addition of the requires clause will give you your
expected result. However I am unfortunately currently unable to compile
this to assure that I am correct.

-Howard
Sep 3 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Bart Samwel | last post by:
Hi everybody, I would really like some help explaining this apparent discrepancy, because I really don't get it. Here is the snippet: void...
14
by: Steven T. Hatton | last post by:
I find writing things such as (*ptr)(arg), and (*ptr), to be at least awkward. I've often thought the following would be useful as an alternative...
7
by: Dilip | last post by:
This is just an academic question but is there any particular reason why this does not work? template<typename T> class Foo { public: Foo(T...
1
by: =?Utf-8?B?c2F0aGVlc2t1bWFy?= | last post by:
In my project i have a component named PTS Engine which is developed in VC++ ..Net 2003. And it is migrated to VC++.NET 2005 version. Initially...
8
by: minseokoh | last post by:
Hi, Could someone explain why "const" is located after the function name and what it means? inline unsigned char *access(int off) const { if...
5
by: sendos | last post by:
Consider the following sample code #include <iostream> using namespace std; class A { public: int x; A(int n = 0) : x(n) {};
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection...
2
by: LewGun | last post by:
at the end of last year Herb Sutter told us that "C++ 0x has been fixed", now GCC4.3 had been released, the compiler were known as "the C ++ new...
0
by: Frank Bergemann | last post by:
Using gcc-4.3.0 it silenty(!) invokes the Test::operator=(Test const& t) for Test a; Test b = std::move(a); Test c = std::moved(T()); - if i...
1
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.