Prev: const is an overrated concept that is a source of extra typing and maintenan
Next: performance of map in MSVC 10b2
From: itaj sherman on 8 Apr 2010 14:57 On Apr 9, 1:59 am, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> wrote: > On 8 Apr., 19:18, itaj sherman <itajsher...(a)gmail.com> wrote: > > > On Apr 8, 12:32 pm, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote: > > > > Here's one cake for you then, to both eat and keep: > > > > template<typename T> > > > T copy(T const& t) > > > { return t; } > > > > iterator i0 = ...; > > > iterator i1 = ++copy(i0); > > > > :) > > > > Uli > > > I'm not sure I get this: how does the temporary returned by copy bind > > to a reference parameter of operator++. Is it some rvalue-reference > > version of operator++? Can it be done in c++03? > > There is no reference binding intended. I think > that Uli just wants to demonstrate that above > code is not guaranteed to be well-formed: For > built-in pointers an lvalue is required for the > preincrement operator, but copy returns an rvalue. > > HTH & Greetings from Bremen, > > Daniel Kr�gler > So, the code doesn't compile unless c++0X with an ::operator++ ( iterator&& ) overload, right? 1) As I said: the parameter of operator++ is non-const reference and cannont bind to the temporary returned by copy. 2) As you said: operator++ expects lvalue parameter and cannot accept rvalue returned by copy. I thought there isn't a difference between 1 and 2, is there? itaj -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Ulrich Eckhardt on 8 Apr 2010 22:36 Daniel Kr�gler wrote: > I think that Uli just wants to demonstrate that above > code is not guaranteed to be well-formed: For built-in > pointers an lvalue is required for the preincrement > operator, but copy returns an rvalue. I wish I hat thought of that, but no, I didn't. Summing up, to get the iterator following an existing one, Itaj Sherman came up with template<typename T> T successor(T t) { return ++t; } iterator i0 = ... iterator i1 = successor(i0); which is also known as boost::next or a future std::next, while Herb Sutter half-jokingly suggested replacing the "successor" with "++T" iterator i0 = ... iterator i1 = ++iterator(i0); However, this becomes inconvenient once the actual name of the iterator becomes largish by spelling out the whole namespace, container, template parameters etc, which is when the type deduction in the successor template function jumps in and eliminates the whole thing. I then proposed using a template function for the copying, which could then deduce the type, and otherwise using the normal operator: template<typename T> T copy(T t) { return t; } iterator i0 = ... iterator i1 = ++copy(i0); Of course, only the successor/boost::next/std::next will work when T is a builtin type, like e.g. a pointer, while the two variants using the copy constructor directly or via a template function don't. Uli -- [ 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 9 Apr 2010 06:16 On 9 Apr., 07:57, itaj sherman <itajsher...(a)gmail.com> wrote: > On Apr 9, 1:59 am, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> > wrote: > > > > > On 8 Apr., 19:18, itaj sherman <itajsher...(a)gmail.com> wrote: > > > > On Apr 8, 12:32 pm, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote: > > > > > Here's one cake for you then, to both eat and keep: > > > > > template<typename T> > > > > T copy(T const& t) > > > > { return t; } > > > > > iterator i0 = ...; > > > > iterator i1 = ++copy(i0); > > > > > :) > > > > > Uli > > > > I'm not sure I get this: how does the temporary returned by copy bind > > > to a reference parameter of operator++. Is it some rvalue-reference > > > version of operator++? Can it be done in c++03? > > > There is no reference binding intended. I think > > that Uli just wants to demonstrate that above > > code is not guaranteed to be well-formed: For > > built-in pointers an lvalue is required for the > > preincrement operator, but copy returns an rvalue. > > > HTH & Greetings from Bremen, > > > Daniel Kr�gler > > So, the code doesn't compile unless c++0X with an ::operator++ > ( iterator&& ) overload, right? No, there is no need for C++0x tools to make the code well-formed. Consider: struct X { X& operator++(); }; template<typename T> T copy(T const& t) { return t; } int main() { X it; X it2 = ++copy(it); } This is well-formed because of the special C++03 rule of member functions without ref- qualification which says that even a non-const member function may bind to an rvalue (see [over.match.funcs]/5). In fact with C++0x we can simulate the behaviour of built-in operator++ for user-defined types: struct X { X& operator++() &; }; With this definition above code would be similarly ill-formed as with built-in operator++. > 1) As I said: the parameter of operator++ is non-const reference and > cannont bind to the temporary returned by copy. > 2) As you said: operator++ expects lvalue parameter and cannot accept > rvalue returned by copy. > > I thought there isn't a difference between 1 and 2, is there? There is a difference between built-in operator++, which expects /unconditionally/ an lvalue and between user-defined operator++, which does not (w/o ref- qualification or with && qualification) HTH & 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! ]
First
|
Prev
|
Pages: 1 2 3 4 Prev: const is an overrated concept that is a source of extra typing and maintenan Next: performance of map in MSVC 10b2 |