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 

Rvalue Reference question: Overloading on whether *this is

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Joe Gottman
Guest





PostPosted: Fri Sep 24, 2004 4:49 pm    Post subject: Rvalue Reference question: Overloading on whether *this is Reply with quote



I have a question about that rvalue reference proposal in the pre-Redmond
mailing
([url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html)[/url]. Is
there any way to overload a member function on whether *this is an lvalue or
an rvalue? Consider the following code:

#include <vector>
#include <string>

vector<string> createVector();

int main() {
vector<string> v(1, "Hello World");
std::string s1 = v[0];
std::string s2 = createVector()[0];
return 1;
}

Since v is an lvalue, s1 has to be created using a copy constructor.
However, since the result of createVector() is an rvalue, theoretically s2
could be created using a move constructor, thus saving the cost of copying
the string. Unfortunately, there seems to be no way to define a member
function that is overloaded on whether *this is an lvalue or an rvalue. For
a non-member function, we can define an overload set as follows:

string const &getElement(vector<string> const &v, size_t index);
//const lvalues
string &getElement(vector<string> &v, size_t index); // non-const
lvalues
string &&getElement(vector<string> &&v, size_t index); //non-const
rvalues

It would be nice if we could do the same thing for member functions

template <class T, class A>
class vector {
...
T const & operator[](size_t index) const;
T & operator[](size_t index);
T && operator[](size_t index) &&; //Use && at end to say *this is
an rvalue reference, similar to const at end on the first function.
};

The third function above would be illegal under the rvalue-reference
proposal in its current form, but I think it should be possible to do
something like this.

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.jamesd.demon.co.uk/csc/faq.html ]

Back to top
David Abrahams
Guest





PostPosted: Fri Sep 24, 2004 5:55 pm    Post subject: Re: Rvalue Reference question: Overloading on whether *this Reply with quote



[email]jgottman (AT) carolina (DOT) rr.com[/email] ("Joe Gottman") writes:

Quote:
I have a question about that rvalue reference proposal in the pre-Redmond
mailing
([url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html)[/url]. Is
there any way to overload a member function on whether *this is an lvalue or
an rvalue?

No. *some_pointer is always an lvalue.

Quote:
Consider the following code:

#include <vector
#include
vector
int main() {
vector<string> v(1, "Hello World");
std::string s1 = v[0];
std::string s2 = createVector()[0];
return 1;
}

Since v is an lvalue, s1 has to be created using a copy constructor.
However, since the result of createVector() is an rvalue, theoretically s2
could be created using a move constructor, thus saving the cost of copying
the string. Unfortunately, there seems to be no way to define a member
function that is overloaded on whether *this is an lvalue or an rvalue. For
a non-member function, we can define an overload set as follows:

string const &getElement(vector<string> const &v, size_t index);
//const lvalues
string &getElement(vector<string> &v, size_t index); // non-const
lvalues
string &&getElement(vector<string> &&v, size_t index); //non-const
rvalues

It would be nice if we could do the same thing for member functions

template class vector {
...
T const & operator[](size_t index) const;
T & operator[](size_t index);
T && operator[](size_t index) &&; //Use && at end to say *this is
an rvalue reference, similar to const at end on the first function.
};

The third function above would be illegal under the rvalue-reference
proposal in its current form, but I think it should be possible to do
something like this.

Hmm. I don't love the syntax, though I agree for symmetry's sake
something like that should be possible. I also think allowing
operator[] to be a non-member is probably a good idea.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ 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.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Howard Hinnant
Guest





PostPosted: Fri Sep 24, 2004 5:56 pm    Post subject: Re: Rvalue Reference question: Overloading on whether *this Reply with quote



In article <JaK4d.7177$zA3.1500343 (AT) twister (DOT) southeast.rr.com>,
[email]jgottman (AT) carolina (DOT) rr.com[/email] ("Joe Gottman") wrote:

Quote:
I have a question about that rvalue reference proposal in the pre-Redmond
mailing
([url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html)[/url]. Is
there any way to overload a member function on whether *this is an lvalue or
an rvalue? Consider the following code:

#include <vector
#include
vector
int main() {
vector<string> v(1, "Hello World");
std::string s1 = v[0];
std::string s2 = createVector()[0];
return 1;
}

Since v is an lvalue, s1 has to be created using a copy constructor.
However, since the result of createVector() is an rvalue, theoretically s2
could be created using a move constructor, thus saving the cost of copying
the string. Unfortunately, there seems to be no way to define a member
function that is overloaded on whether *this is an lvalue or an rvalue. For
a non-member function, we can define an overload set as follows:

string const &getElement(vector<string> const &v, size_t index);
//const lvalues
string &getElement(vector<string> &v, size_t index); // non-const
lvalues
string &&getElement(vector<string> &&v, size_t index); //non-const
rvalues

It would be nice if we could do the same thing for member functions

template class vector {
...
T const & operator[](size_t index) const;
T & operator[](size_t index);
T && operator[](size_t index) &&; //Use && at end to say *this is
an rvalue reference, similar to const at end on the first function.
};

The third function above would be illegal under the rvalue-reference
proposal in its current form, but I think it should be possible to do
something like this.

That's an interesting suggestion. Section 13.3.1, in describing
overload resolution and member functions, describes member functions as
having an implicit object parameter with type cv X&, except that it will
also bind to rvalue X even if cv does not contain const. In other
words, C++98, rewritten with the syntax, but not the capabilities of
N1690, says that member functions are transformed into the following for
the purpose of overload resolution:

class X
{
R f(A1, A2, ...);
};

R X::f(A1, A2, ...);

becomes:

R f(X&&, A1, A2, ...); // C++98

I.e. the X&& already exists in C++98, but is only available to the
compiler, and only in the context of binding the implicit object
parameter.

Your suggestion would require a way to overload on the implicit object
parameter with respect to lvalue/rvalue (we already can with respect to
cv qualifiers). The ironic part is that in C++98, there is currently no
way to specify an implicit object parameter with an lvalue reference! :-)

R f(X&, A1, A2, ...); // not doable in C++98!

I believe the trick in implementing your suggestion is to figure out how
to allow the above pseudo signature without breaking backward
compatibility.

Getting back to your example:

T & operator[](size_t index); // 1
T && operator[](size_t index) &&; // 2

We have 2 today (except of course for the return type), and 1 is really
what you're requesting. Therefore in the interest of backwards
compatibility the syntax would have to look something like:

T & operator[](size_t index) &; // 1
T && operator[](size_t index); // 2

Although I suppose we could put the decoration on 2, but tell the
compiler to vary the implicit object parameter on the undecorated 1
according to whether or not the decorated 2 actually existed in the
overload set. Whether or not that is too complicated for the compiler,
I'm not in a position to say.

I'm stopping short of actually recommending such a proposal (nor do I
oppose it). My post is merely meant to clarify what the situation is.

If overloading on the implicit object parameter rvalue/lvalue-ness is
not deemed practical, the client can still force the issue:

std::string s2 = move(createVector()[0]);

-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.jamesd.demon.co.uk/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
Page 1 of 1

 
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.