From: itaj sherman on
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
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
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! ]