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 

Constrained Forwarding(R-Value Reference)
Goto page 1, 2, 3, 4  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: Thu Feb 15, 2007 5:44 am    Post subject: Constrained Forwarding(R-Value Reference) Reply with quote



The current proposed wording addresses perfect forwarding as
following:

template< typename T>
void fo(T&& t); // T&& deduced as a l-value reference if the argument
is a l-value; r-value reference otherwise.

However, there might be some cases where we need **constrained**
forwarding, such as:

template<typename T>
void fo(MyC<T>&& t);

But in this case t would always be deduced as a r-value reference.
One alternative is to use traits:

template<typename T>
void fo(T&& t, is_my_c<T>::type* = 0);

This, despite being practical, is a little unwieldy.

Are there any better solutions?

---
[ 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
Grizlyk
Guest





PostPosted: Mon Feb 19, 2007 5:33 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote



pongba (AT) gmail (DOT) com wrote:
Quote:

The current proposed wording addresses perfect forwarding as
following:

template< typename T
void fo(T&& t); // T&& deduced as a l-value reference if the argument
is a l-value; r-value reference otherwise.

However, there might be some cases where we need **constrained**
forwarding, such as:

template<typename T
void fo(MyC<T>&& t);

But in this case t would always be deduced as a r-value reference.
One alternative is to use traits:

[skipped]

Are there any better solutions?


It is not clear to me how "r-value reference" must be implemented. I can
understand, that concrete listed conditions for "r-value reference" can
exist in nature, but I have been unable to guess how "r-value reference"
should be implemented.

As for me, the "r-value reference" looks like irregular patch to language
structure to solve some limited circle of problems.

After reading some pages about "r-value reference" I can not answer:

---
1. How I must declare copyable and moveable properties for my class.

---
2. How concrete property can be passed to concrete function, expected either
"copyable" or "movable".

(Note, there are differences in implementation of the function with
different "able"

template<class T>
void foo(const copyable T obj)
{
const T tmp(obj); //ok
obj.method(); //ok
obj.method(); //ok
return tmp; //ok
}

template<class T>
void foo(const moveable T obj)
{
const T tmp(obj); //ok, but obj is no longer valid
obj.method(); //error "tmp" must be used
obj.method(); //error "tmp" must be used
return tmp; //ok
}

In fact, "foo" implementation must be different for copyable and moveable,
because moveable is more restricted than copyable and moveable can not be
declared with the help of "non-const".

Anyway, programmer must know what kind of "able" is used here.)

--
Maksim A. Polyanin


---
[ 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: Mon Feb 19, 2007 8:36 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote



On Feb 19, 7:33 am, grizl...@yandex.ru ("Grizlyk") wrote:
Quote:
pon...@gmail.com wrote:

The current proposed wording addresses perfect forwarding as
following:

template< typename T
void fo(T&& t); // T&& deduced as a l-value reference if the argument
is a l-value; r-value reference otherwise.

However, there might be some cases where we need **constrained**
forwarding, such as:

template<typename T
void fo(MyC<T>&& t);

But in this case t would always be deduced as a r-value reference.
One alternative is to use traits:

[skipped]

Are there any better solutions?

It is not clear to me how "r-value reference" must be implemented. I can
understand, that concrete listed conditions for "r-value reference" can
exist in nature, but I have been unable to guess how "r-value reference"
should be implemented.

As for me, the "r-value reference" looks like irregular patch to language
structure to solve some limited circle of problems.

After reading some pages about "r-value reference" I can not answer:

---
1. How I must declare copyable and moveable properties for my class.

No you don't have to. You can just have a plain-old-copyable-but-not-
moveable class.
Moveable is an optional property.

Quote:

---
2. How concrete property can be passed to concrete function, expected either
"copyable" or "movable".

(Note, there are differences in implementation of the function with
different "able"

template<class T
void foo(const copyable T obj)
{
const T tmp(obj); //ok
obj.method(); //ok
obj.method(); //ok
return tmp; //ok

}

template<class T
void foo(const moveable T obj)
{
const T tmp(obj); //ok, but obj is no longer valid
obj.method(); //error "tmp" must be used
obj.method(); //error "tmp" must be used
return tmp; //ok

}

In fact, "foo" implementation must be different for copyable and moveable,
because moveable is more restricted than copyable and moveable can not be
declared with the help of "non-const".

Anyway, programmer must know what kind of "able" is used here.)

I'm not following you here. But I recommend that you read
N1377/1385/1610/1690/1770/1771/1784/1821/1855/1952/2027/2118.

---
[ 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 Feb 21, 2007 2:50 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

In article <erdo82$mtu$1 (AT) aioe (DOT) org>, grizlyk1 (AT) yandex (DOT) ru ("Grizlyk")
wrote:

Quote:
I'm not following you here. But I recommend that you read
N1377/1385/1610/1690/1770/1771/1784/1821/1855/1952/2027/2118.

I will try, but it is something wrong here - too many Nxxx to read to
understand how to do so trivial thing.

Start with:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

"A Brief Introduction to Rvalue References"

It is short, and has an example of adding a move constructor and move
assignment operator to a class (search for "clone_ptr").

The goal of this document is to get you sufficient knowledge to work
with rvalue references with a very small read. Please feel free to send
me back comments on this document as I would like to continue to refine
my ability to quickly and easily explain the rvalue reference.

-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
Grizlyk
Guest





PostPosted: Thu Mar 01, 2007 12:13 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

Howard Hinnant wrote:
Quote:

Start with:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

"A Brief Introduction to Rvalue References"

It is short, and has an example of adding a move constructor and move
assignment operator to a class (search for "clone_ptr").

The goal of this document is to get you sufficient knowledge to work
with rvalue references with a very small read. Please feel free to send
me back comments on this document as I would like to continue to refine
my ability to quickly and easily explain the rvalue reference.

Hello.

1. No auto_ptr support.
=======================

I agree, that any kind of move semantic support is useful in C++ as itself,
but we have a special requirements to select concrete forms of the move
semantic support. One of the important requirements is all what we need for
implementation of auto_ptr idiom as fast and effective manager of dynamic
memory, because auto_ptr is using move semantic to pass ownership.

The auto_ptr is RAII memory wrapper and can be implemented as free-standing
class with very light methods and its internal state has only one POD
pointer. It is really one of the most effective wrappers that is why
auto_ptr idiom is attractive and we are speaking about it here.

I can say, that in present days any auto_ptr implementation without
appearance of special C++ improvements (the improvements have been directed
exactly to support auto_ptr idiom) can be described as "elbow is close, but
to not bite", only teeth clattering in vain.

In the http reference (you have published here) one have written:

ref> Rvalue references allow programmers to avoid logically unnecessary
ref> copying and to provide perfect forwarding functions.
ref>
ref> It turns out that the combination of rvalue references
ref> and lvalue references is just what is needed to easily
ref> code move semantics.

and move semantic have introduced "in general" there, without taking into
account the concrete auto_ptr requirements. The target of auto_ptr support
is not listed there and as i can understand after reading, the published
general form of move semantic unfortunatelly is not suitable for auto_ptr,
because can not help us to write safe auto_ptr implementation.

So do we need the C++ movable that can not support even auto_ptr? I think
no. The "r-value reference" is good, but not enough. I will try to explain
it below.


2. No ordered definitions
for "copyable" and "moveable" C++ concepts.
==============================================

One have said

ref> Rvalue references is a small technical extension to the C++ language

The "small extension" is impossible for "moveable". We need "copyable" and
"moveable" concepts integrated to C++ completely.

As I know, today C++ has no strict definition for copyable and moveable
objects. That is why one thinks that non-const copy constructor T(T&) is
suitable for copyable objects, other does not agree and does think, that
moveable must be always declared as non-const, so thinks that non-const copy
constructor T(T&) probably is suitable for moveable objects.

The kind of "undefinined behaviour" and confusions must be eleminated.

See page http://grizlyk1.narod.ru/cpp_new/index.htm#14 about the problem
(the page is under construction so can be changed in future without
advertisements).

Also you can see my thread "How to describe any type of parameter passed to
function" in the group. The thread is enumerating some questions, what must
be answered. Really, I can not answer to the questions after have read http
reference published by you, maybe information is not enough or I do not know
something unrelated to r-value reference?

For example, try to use your r-value reference to express the following
statements (the sign "@" has been randomly taken only to define moveable
type):

//copyable variable
type var;
//moveable variable
type @var;

//reference to copyable variable
type &var;
//reference to moveable variable
type & @ var;

//parameter: copyable variable passed by value
void foo([const] type name);
//parameter: moveable variable passed by value
void foo([const] type @name);

//parameter: copyable variable passed by reference
void foo([const] type& name);
//parameter: moveable variable passed by reference
void foo([const] type& @name);

We want to use "move constructor" as well as "copy constructor", that is why
we are forced to mark variable to define what kind of constructor must be
used to create new value. Consider:

template<class type>
//parameter: moveable variable passed by value
type@ foo(const type @param)
{
type a; //default ctor used
type @b; //the same as a

type c(param); //copy ctor used if exist else error
type @d(param); //move ctor used
type @e(param); //error - double move

return d; //move ctor used
}


3. "Value" is not the same as "reference".
==========================================

In your example one have declared constructor for r-value reference

ref> // move semantics
ref> clone_ptr(clone_ptr&& p)
ref> : ptr(p.ptr) {p.ptr = 0;}


Look, it is really consructor of new instance from non-const one. But word
"reference" means "do not make new copy".

clone_ptr a;
//due to "reference" we are expecting "b" is the same as "a"
//but b is kind of copy of a
clone_ptr&& b(a);

I do not know why we must call "moveable value" as "reference" - it is only
point of confusions. And if "moveable value" is "reference" then what is
"moveable reference"?


4. "Non-const" is not the same as "moveable".
=============================================

One have used non-const parameter:

ref> clone_ptr(clone_ptr&& p)

But moveable is special case of "mutable" and often moveable must be called
as "once" rather than "non-const". The most important thing is that only
knowledge that a variable is non-const can not help us to safe work with the
kind of moveable.

Example of the behaviour is of course auto_ptr implementation. The ownership
from auto_ptr can not be transferred more than one time (_independently from
const attribute_).

See page http://grizlyk1.narod.ru/cpp_new/index.htm articles #11-#15 about
the C++ improvement for safe usage of the kind of moveable (the page is
under
construction so can be changed in future without adverticements).

Probably we can find in future other requirements for moveable and copyable,
so i think the best way to do moveable support - to make implementation of
moveable concept for C++ "in general" - as well completely integrated to
C++, as copyable can be done.


5. What if parameter can not be passed by reference?
====================================================

As i have said, the ownership from auto_ptr can not be transferred more than
one time.

In order compiler take the correct ownership transferring under control,
lifetime of auto_ptr must be limited by local scope or anyway compiler must
trace creation and erasing any object of auto_ptr class.

That is why auto_ptr often _can not be passed by any reference_. We must
pass the auto_ptr to functions only by value. In order to do it we need to
get control (at least disable/enable) for each possible way in which
parameter can be passed to function (for example declaring some members of
class as public/protected).

See the same articles http://grizlyk1.narod.ru/cpp_new/index.htm#15 about
it.


6. Interaction "copyable" and "moveable".
=========================================

Today we have only copyable/non-copyable support, that looks like boolean
type. But adding new property as moveable gives to object one of the
following ordered property: non-copyable/moveable/copyable.

And here we must define strict rules also ("functions expecting moveable
value can use copyable value" and so on).


--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new





---
[ 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 Mar 01, 2007 7:33 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

On Feb 28, 6:13 pm, grizl...@yandex.ru ("Grizlyk") wrote:
Quote:

1. No auto_ptr support.
=======================


It is intended that unique_ptr be a 'fixed' version of auto_ptr:

http://home.twcny.rr.com/hinnant/cpp_extensions/unique_ptr.html

Quote:

2. No ordered definitions
for "copyable" and "moveable" C++ concepts.
==============================================


Have you checked out the concepts proposal for C++0x?

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf

I believe the combination of concepts and rvalue references will do
all you're suggesting. (I don't know if there are concrete proposals
for concepts to do with move semantics, yet - I seem to remember
seeing some).

Quote:

We want to use "move constructor" as well as "copy constructor", that is why
we are forced to mark variable to define what kind of constructor must be
used to create new value. Consider:

template<class type
//parameter: moveable variable passed by value
type@ foo(const type @param)
{
type a; //default ctor used
type @b; //the same as a

type c(param); //copy ctor used if exist else error
type @d(param); //move ctor used
type @e(param); //error - double move

return d; //move ctor used

}


It's not clear exactly what you're trying to do, but as far as I can
tell, in C++0x this is likely to look something like

template <Movable type>
type foo(type&& param)
{
type a, b;
type c(param); // compile-time error if param not copyable
type d(std::move(param));
type e(std::move(param)); // not a compile-time error in C++0x

return std::move(d);
}

So, the substantive difference between what you suggest and the rvalue
reference proposal is about whether to make double-move a compile-time
error somehow. The consensus seems to be that the disadvantages
outweigh the advantages.


Quote:
3. "Value" is not the same as "reference".
==========================================

In your example one have declared constructor for r-value reference

ref> // move semantics
ref> clone_ptr(clone_ptr&& p)
ref> : ptr(p.ptr) {p.ptr = 0;}

Look, it is really consructor of new instance from non-const one. But word
"reference" means "do not make new copy".


Note that 'clone' means 'copy'. I think with that in mind, you'll
understand the example.

Quote:

4. "Non-const" is not the same as "moveable".
=============================================


In the rvalue reference proposal, moving is explicit (using
std::move), except from temporaries (rvalues).

Quote:

5. What if parameter can not be passed by reference?
====================================================

As i have said, the ownership from auto_ptr can not be transferred more than
one time.

In order compiler take the correct ownership transferring under control,
lifetime of auto_ptr must be limited by local scope or anyway compiler must
trace creation and erasing any object of auto_ptr class.

That is why auto_ptr often _can not be passed by any reference_.


We'll have unique_ptr; it will not normally be passed by reference,
like auto_ptr today.

Quote:

6. Interaction "copyable" and "moveable".
=========================================

Today we have only copyable/non-copyable support, that looks like boolean
type. But adding new property as moveable gives to object one of the
following ordered property: non-copyable/moveable/copyable.

And here we must define strict rules also ("functions expecting moveable
value can use copyable value" and so on).


I think if you study the rvalue reference proposal, you'll find all
this is covered. It does seem you are criticising without having taken
the time to understand what is being proposed.


James

---
[ 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
Grizlyk
Guest





PostPosted: Sat Mar 03, 2007 10:10 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

tasjaevan (AT) gmail (DOT) com wrote:
Quote:

1. No auto_ptr support.
=======================


It is intended that unique_ptr be a 'fixed' version of auto_ptr:

http://home.twcny.rr.com/hinnant/cpp_extensions/unique_ptr.html

You can call auto_ptr as unique_ptr, but the question remains: unique_ptr
can not be safe implemented with the help of "r-value reference" and i have
tryed to explain it in my previous post with the help of 6 points of
disagreement.

Quote:

2. No ordered definitions
for "copyable" and "moveable" C++ concepts.
==============================================


Have you checked out the concepts proposal for C++0x?

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf

I believe the combination of concepts and rvalue references will do
all you're suggesting. (I don't know if there are concrete proposals
for concepts to do with move semantics, yet - I seem to remember
seeing some).

I do not need any beleif here and more - i have tryed to explain it in my
previous post with the help of 6 points of disagreement.

By the way, the previous considered definition of the "r_value reference" is
completed and does not require any extra definitions in addition to use the
"r_value reference". So it is enough to see that the "r_value reference" can
not be improved by any other definitions.

Quote:

We want to use "move constructor" as well as "copy constructor", that is
why we are forced to mark variable to define what kind of constructor
must be used to create new value. Consider:

template<class type
//parameter: moveable variable passed by value
type@ foo(const type @param)
{
type a; //default ctor used
type @b; //the same as a

type c(param); //copy ctor used if exist else error
type @d(param); //move ctor used
type @e(param); //error - double move

return d; //move ctor used

}


It's not clear exactly what you're trying to do,

What concrete line of the code above have made confusions?

Quote:
but as far as I can tell,
in C++0x this is likely to look something like

template <Movable type
type foo(type&& param)

Probably you want to say
type&& foo(type&& param)

else in return statement:
Quote:
return std::move(d);

you can not return like this in C++, because you target is "type value", but
"std::move(d)" returns "move_return_type value", so we need cast here and
the return expression will be unrolled in C++ to

type temporary(std::move(d)); //constructor "type(move_return_type&)"
return temporary; //error "type" is not copyable

Quote:
{
type a, b;

type c(param); // compile-time error if param not copyable
type d(std::move(param));
type e(std::move(param)); // not a compile-time error in C++0x

The three lines above are constructors of class "type" and expression "type
d(std::move(param))" uses constructor "type(move_return_type&)".

We of course can _not_ use the trivial explicit cast for moveable in
practial cases, because we often need _implicit_ return value without
explicit "std::move" ( more - auto_ptr(unique_ptr) require to have a
kind of _implicit, hidden_ constructor to pass ownership ).

We need to say

type&& d(param);
type&& e(param); // not a compile-time error in C++0x

and we need assuming that for the two lines above due to "type&&" will be
called any kind of constructor "type(const type&&)" instead of "type(const
type&)".

Quote:
return std::move(d);

Probably you want to say
return d;

Quote:
}

So, the substantive difference between what you suggest and the rvalue
reference proposal is about whether to make double-move a compile-time
error somehow. The consensus seems to be that the disadvantages
outweigh the advantages.

Any could call "moveable value" as "r-value reference", but we can not
invent any language stuff for "moveable value" better than total
integration of "moveable" attribute into language, similar to constness (see
below).

Do we need to explode all ordinary names, rules and conventions in C++ to be
compatible with "r-value reference" (in ordinary value sense (not in
reference sense)) instead of to be compatible with "moveable" attribute?
Note, "moveable" attribute do not require the mistery.

Probably "r-value reference" is useful to be reference to rvalue, but
useless to be substitute of "moveable value".

So you see that not only "double-move detection at compile-time" is
disagreement, and other 5 marked points of disagreement have been posted by
me in previous post also prove it.

By the way, I want to say, that "double-move detection at compile-time" is
so important thing for "practical programming with moveable" as well as
"assignment to const compile time detection". Without "double-move detection
at compile-time" programming with "moveable" is dangerous.

I think the source of problem is due to C originally has no "moveable
concept" only "copyable" and for "copyable" the "move" and "destroy" is
simultaneous operations, unlike "moveable", "copyable" normally can not be
accessable during incorrect sate.


Quote:
3. "Value" is not the same as "reference".
==========================================

In your example one have declared constructor for r-value reference

ref> // move semantics
ref> clone_ptr(clone_ptr&& p)
ref> : ptr(p.ptr) {p.ptr = 0;}

Look, it is really consructor of new instance from non-const one. But
word
"reference" means "do not make new copy".


Note that 'clone' means 'copy'. I think with that in mind, you'll
understand the example.

Can not be any "in mind". Either an expression do copy/move value or do not
and using reference (address) to other object instead. It can not be joined
or mixed.

Quote:
I do not know why we must call "moveable value" as "reference" - it is
only point of confusions. And if "moveable value" is "reference"
then what is "moveable reference"?

If assuming that "r-value reference" is "mobeable value" (ugly assuming)
then for "mobeable reference" must we use ordinary reference? We can not
use "reference to copyable" as "reference to moveable", because we lost
information about moveable restrictions in functions that take reference (we
can not express with "r-value reference" that function expect reference only
to copyable or only to moveable).

It is evidently, "moveable" is the same "limiter" as "const", you can not
invent any kind of simple "const-value reference" to express constness and
for the "moveable" also can not. If you do not like sign "@" use word
"moveable", similarly to word "const", so for previouse example can be like
this:

Quote:
template<class type
//parameter: moveable variable passed by value
type moveable foo(const type moveable param)
{
type a; //default ctor used
type moveable b; //the same as a

type c(param); //copy ctor used if exist else
error
type moveable d(param); //move ctor used
type moveable e(param); //error - double move

return d; //move ctor used

}


Quote:

4. "Non-const" is not the same as "moveable".
=============================================


In the rvalue reference proposal, moving is explicit (using
std::move), except from temporaries (rvalues).

Do you agree that "non-const" is not the same as "moveable" or not? If not
try to prove your opinion.

Quote:

5. What if parameter can not be passed by reference?
====================================================

As i have said, the ownership from auto_ptr can not be transferred more
than
one time.

In order compiler take the correct ownership transferring under control,
lifetime of auto_ptr must be limited by local scope or anyway compiler
must
trace creation and erasing any object of auto_ptr class.

That is why auto_ptr often _can not be passed by any reference_.


We'll have unique_ptr; it will not normally be passed by reference,
like auto_ptr today.

What kind of language/unique_ptr features protect us from passing unique_ptr
by reference?

Quote:

6. Interaction "copyable" and "moveable".
=========================================

Today we have only copyable/non-copyable support, that looks like boolean
type. But adding new property as moveable gives to object one of the
following ordered property: non-copyable/moveable/copyable.

And here we must define strict rules also ("functions expecting moveable
value can use copyable value" and so on).


I think if you study the rvalue reference proposal, you'll find all
this is covered.

I wanted to say If we will add normal "moveable" attribute, we are forced to
declare the strict interaction rules also.

The "rvalue reference" is partially substituting the "moveable" attribute,
so the thing can not be good covered by any other complete attribute, the
"rvalue reference" is one of the irregular stuff in C++.

Quote:
It does seem you are criticising without having taken
the time to understand what is being proposed.

I think the better way to be right is just prove that concrete arguments of
your opponent is incorrect, without any abstract suspicions or abstract
references. I have post tons of _concrete_ examples on the page
http://grizlyk1.narod.ru/cpp_new articles #11-#15.

The _concrete_ examples show that "r-value reference" can not be used, that
with the help "r-value reference" it will be impossible to implement safe
moveable in general (and concrete simplest case as auto_ptr (uniq_ptr)
also ) in C++ even in theory. Can you say any _concrete_ against the
_concrete_ examples?

Outcome:

I know, there are many peolple who are happy to have even current
std::auto_ptr implementation. I do not argue, as they wish, but just let's
include into language all necessary features to make moveable classes
implementation is possible and all other people could make own classes under
own conditions.


--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new





---
[ 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: Sat Mar 03, 2007 4:24 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

On 3 mar, 04:34, grizl...@yandex.ru ("Grizlyk") wrote:

Quote:
The _concrete_ examples show that "r-value reference" can not be used, that
with the help "r-value reference" it will be impossible to implement safe
moveable in general (and concrete simplest case as auto_ptr (uniq_ptr)
also ) in C++ even in theory. Can you say any _concrete_ against the
_concrete_ examples?

With the help of Howard Hinnant and others Russell Yanofsky has
produced a modified GCC 4.3 with support for Rvalue References.
You can download the source code here:

http://russ.yanofsky.org/rref/

Based on his work I have a partial implementation of the
Recommendations for the Standard Library, including Howard's
implementation of unique_ptr and optimizations for string, vector and
deque.
You can download my patch here:

http://mndfck.org/~pedro.lamarao/projects/c++0x/libstdc++-v3.patch

Care to provide an example program that exhibits this fundamental
failure you keep mentioning?

--
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
Grizlyk
Guest





PostPosted: Sun Mar 04, 2007 3:56 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

Pedro Lamarão wrote:
Quote:

The _concrete_ examples show that "r-value reference" can not be used,
that
with the help "r-value reference" it will be impossible to implement safe
moveable in general (and concrete simplest case as auto_ptr (uniq_ptr)
also ) in C++ even in theory. Can you say any _concrete_ against the
_concrete_ examples?

With the help of Howard Hinnant and others Russell Yanofsky has
produced a modified GCC 4.3 with support for Rvalue References.
You can download the source code here:

http://russ.yanofsky.org/rref/

Based on his work I have a partial implementation of the
Recommendations for the Standard Library, including Howard's
implementation of unique_ptr and optimizations for string, vector and
deque.
You can download my patch here:

http://mndfck.org/~pedro.lamarao/projects/c++0x/libstdc++-v3.patch

Care to provide an example program that exhibits this fundamental
failure you keep mentioning?

Nice answer. Are you offering to write own patch for GCC 4.3 myself to
support "moveable concept"?

The existence of the implementation is really interesting thing, but I do
not argue, that can be many kind of possible implementation of "moveable",
but i only think, that "r-value reference" is one of the irregular one.

So i more expect answers about problems, detected in "r-value reference",
which can not be avoided by any implememtation even in theory, not only in
GCC 4.3.

Maybe I am not right, but sometimes I think, that "r-value reference" has
appeared from the idea: "sign '&&' exist, but never used" Smile. Speaking
seriously, "r-value reference" does not solve problem of "safe moveable"
("compile time double move detection"), does not make differences between
"non-const" and "moveable", makes strange for C++ and unexplainable in
theory mixing "value" and "reference" terms and so on.

I can repeat, unexplainable because no one can invent replacement for two
diffrent types of data ("value" and "reference") by one type of data called
"special reference":

in the first example "p", declared as "clone_ptr&&", has been passed by
reference (only address of "p" used):

ref> // move semantics
ref> clone_ptr(clone_ptr&& p)
ref> : ptr(p.ptr) {p.ptr = 0;}

but in second example "return type of foo", declared as "clone_ptr&&",
already will be returned by value (address of "p" can not be used)

clone_ptr&& foo()
{
clone_ptr p;
return p;
}

The both different kind of operation is expressed by the same "clone_ptr&&"
declaration and function, returning value, declared exactly as constructor,
obtaining reference. It is wrong, because looking on declaration
"clone_ptr&&" it is impossible to understand what exactly will be done.

I very, very, very long time (long for so simple stuff) even can not
understand (probably still can not understand) what the "r-value reference"
is going to do, because its behaviour contradicts to all other C++
conventions without any reasons.

Looking from "regular moveable concept" side, I think the "r-value
reference" supports only "moveable value" rather than "moveable reference".

I think, that the source of the "r-value reference" error is based on the
fact, that during creating of "r-value reference" idea, its author was
working closely only with copy constructors, but in copy constructor we can
not use value, only reference, so in copy constructor the problem is hidden
and can be overlooked. If building of "r-value reference" idea has been
started from considering general functions instead of copy constructors, the
"r-value reference" never has been appeared in the world.

--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new



---
[ 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: Tue Mar 06, 2007 11:52 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

In article <esdvnk$t8v$1 (AT) aioe (DOT) org>, "Grizlyk" <grizlyk1 (AT) yandex (DOT) ru>
wrote:

Quote:
"safe moveable"
("compile time double move detection")

How does the compiler do this? It seems to me that whether or not an
object has been moved from is intrinsically run time information that
can not, in general, be had at compile time.

For example (I will try to use your syntax but I'll probably also get
your syntax wrong, sorry):

bool foo();

class A {...};

int main()
{
A a1
if (foo())
{
A @a2(a1);
...
}
// Has a1 been moved from here?
A @a3(a1); // error or not?
}

-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
Grizlyk
Guest





PostPosted: Thu Mar 08, 2007 7:09 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

Howard Hinnant wrote:

1.
Quote:

"safe moveable"
("compile time double move detection")

How does the compiler do this? It seems to me that whether or not an
object has been moved from is intrinsically run time information that
can not, in general, be had at compile time.

Fortunatelly to us, compiler easy can do "compile time testing" in most
_very_ important cases (as for auto_ptr(unique_ptr)). It is very important
becase we will be able to make good reliable replacement of "garbage
collector" _without_ any overhead.

For all other less important cases compiler will generate warning about
"undefined behaviour".

I think, our case of existing "compile time testing" can be compared with
existing of RAII idiom: C++ has designed as hard-linked for RAII, if you do
not know the idiom or will struggle with RAII, you always will get troubles.
Here the same: if you will struggle with "compile time attributes", you
always will get warning about "undefined behaviour" and never will get the
warnings in opposite case of correct design.

Concrete examples with explanations we can find in my page:
http://grizlyk1.narod.ru/cpp_new articles #11-#15.


Quote:
For example (I will try to use your syntax but I'll probably also get
your syntax wrong, sorry):

If you confused with "@" sign just use "moveable" keyword. The "moveable"
can be applied exactly as "const" keyword.

Quote:

bool foo();

class A {...};

int main()
{
A a1
if (foo())
{
A @a2(a1);
...
}
// Has a1 been moved from here?
A @a3(a1); // error or not?

You can get warning here (if foo() body is not known) that "compiler lost
compile time control due to runtime condition".

I can repeat again: if you will struggle with "compile time attributes", you
always will get warning about "undefined behaviour" and never will get the
warnings in opposite case of correct design. Coreect desing can be like
this:

Quote:
A a1
if (foo())
{
A @a2(a1);
...
}

else
{

Quote:
// Has a1 been moved from here?
A @a3(a1); // error or not?

}

Now all OK. You must take in account, that "moveable" is specific and
_limited_ data type, as "const", we can not use limited type in free manner.
We can not write for example like this:

{
const int *const readonly code segment ptr=0x0C800;
int *const tmp=const_cast<int*>(ptr);

//no compile time errors in attempts to write into ROM.
*tmp=0;
}

in order to prove that "const" is unsuitable for C++ attribute.

Let's consider improved example:

A a1;

if (foo())
{
moveable A a2(a1);
...
}
else
{
// Has a1 been moved from here?
moveable A a3(a1); // error or not?
}

All depending from declaration of your class A. There are no predefined
rules for "moveable", as no predefined rules for "const" members. Consider:

A a1

means ordinary copyable object created by default ctor.

moveable A a2(a1);

means moveable object created by "move ctor". It is opposite to:

A a2(a1);


means copyable (copyable is default, so we do not need special keyword)
object created by "copy ctor".

Let's class A has the following declaration:

class A
{
public:
A(const A&); //"copy ctor" means the class is copyable
A(const moveable A&); //"move ctor" means the class is moveable
};

What if we have no declaration of "copy ctor" or "move ctor"? This is
interaction of the following class attributes:
non-copyable/moveable/copyable

This is sorted class attributes:

"non-copyable"
"moveable" can be "non-copyable"
"copyable" can be "moveable" and "non-copyable"

Note, that "non-copyable" is not the same as "singleton", in other words we
are forced to be "non-copyable" - we want to do copy or move, but can not.

In the case of existing only "non-copyable/copyable" class attributes, the
attributes have boolean interaction. For more than two class attributes (as
we have) the interaction is more complex and probably some of the
interaction's rules will be selected with random rationale.

In our simple case it is evidnently, that:

- if the class A has both "copy ctor" and "move ctor", the "copy ctor" will
be used for creation of copyable and "move ctor" for creation of moveable,

- if the class A has only "copy ctor" (has no "move ctor"), the "copy ctor"
will be used instead of "move ctor" (there is no real moving here, but
template that reqired at least moveable will work with copyable also),

- if the class A has only "move ctor" (has no "copy ctor"), the "move ctor"
can not be used instead of "copy ctor".


Quote:
// Has a1 been moved from here?
A @a3(a1); // error or not?

In order to answer we must declare members attributes: "ctor,dtor,once" etc.

The considered example is more difficult to learn compile time attributes
due to reference, because "moveable reference" is more complex thing than
"moveable value" due to nature of "moveable" data type.

More simple example of attributes with detailed explanations one can find in
my page: http://grizlyk1.narod.ru/cpp_new article #13

In our case we can write:

class A
{
public:
//"copy ctor" means the class is copyable
A(const A&) ctor;
//"move ctor" means the class is moveable
A(const moveable A& :(ctor;dtor) ) ctor;
};

Fortunatelly, the behaviour can be assumed as default for constructors and
assignment from the class operator, so we no need write most of the
attributes explicitly for them. Including the attributes can be switched on
if "move ctor" or "move assignment" is declared, so the following example is
the same as above:

class A
{
public:
//"copy ctor" means the class is copyable
A(const A&);
//"copy assignment" means nothing
any_type operator= (const A&)ctor;

//"move ctor" means the class is moveable
A(const moveable A& );
//"move assignment" means nothing
any_type operator= (const moveable A&)ctor;
};

Note, we need place explicit "ctor" for "copy/move assignment" unlike to
constructors, because "assignment" is not always "ctor".


And consider "move ctor" declaration:

//"move ctor" means the class is moveable
A(const moveable A& obj:(ctor;dtor) ) ctor;

means "obj" expects "ctor" state attribute from caller and turns the caller
into "dtor" state. With auto_ptr we can think that ":(ready;dtor)"
attributes can be default for "move ctor" instead of ":(ctor;dtor)"
attributes, ("ready" state means that the object is created and correctly
initialized):

class A
{
public:
//created but not ready, can not copy the object
A();

//"move ctor" means the class is "moveable"
A(const moveable A& :(ready;dtor) )ready;
//"move assignment" means nothing
any_type operator= (const moveable A& :(ready;dtor) )ctor ready;

private:
//private "copy ctor" means the class is "non-copyable"
A(const A&);
any_type operator= (const A&);
};


So we get:

Quote:
int main()
{
A a1

"copy ctor" used, state "ctor"

Quote:
if (foo())
{
A @a2(a1);

"move ctor" used to create "a2"
"a1" must be "ctor" befor and became "dtor"

Quote:
...
}

else
{

Quote:
// Has a1 been moved from here?
A @a3(a1); // error or not?

"move ctor" used to create "a3"
compile time error: "a1" must be "ctor" befor, but "dtor"

}

And again for runtime condition: if you want to have runtime condition, you
can suppress warning with attribute "runtime" like this:


Quote:
int main()
{
A a1
if (foo())
{
A @a2(a1);
...
}

a1:(runtime);

from the point compiler will not trace "a1" attributes for you,
do it yourself

a1:(ctor);

you are sure, that from the point "a1" is "ctor" without explicit "else"
from the point compiler will do trace "a1" attributes again from "ctor"
state

Quote:
// Has a1 been moved from here?
A @a3(a1); // error or not?

a1:(dtor)

you are sure, that from the point "a1" has "dtor" attribute.

A a4:(runtime);

you can declare "a4" without attributes.

More about runtime one can find in my page: http://grizlyk1.narod.ru/cpp_new
arcticle #14.

2.

I think "r-value reference" in general is right desire, but unfortunatelly
has been implemented in wrong direction. It is always hard to select
excellent direction from first step, so the better solution in the case is
changing direction to support more flexible syntax and semantics, to
eliminate detected errors.

Take a look, we no need _any_ explanations for _any_ C++ programmer for the
following construction:

class type;
moveable type foo(const moveable type&);
type& boo(const type&);
moveable type& voo(const moveable type);

The construction is clear, useful, orthogonal with ordinary declarations and
upgradeable in future.

And we need tons of the detailed explanations for the following
construction, that even can not do the same:

class type;
type&& foo(type&&);

The construction is vague, often useless, conflicts with ordinary
declarations, can not cover all possible cases (has limited abilities) and
has no way to upgrade.

The "r-value reference" is worse in comparison with "integrated C++
moveable" concept.


I know, there is opinion, that:
"
1. ...syntax more consistent with [old] would not help programmers
understand [new] better, may reduce initial anxiety, but the resemblance
would only be skin-deep.

2. New ideas and constructs should have new syntax, to emphasize that they
are different from existing ideas constructs
"

But "r-value reference" is a kind of "new idea" that is very integrated into
old terms of C++, we must not explode old ideas for the sake of "new ideas".


--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
(write http://grizlyk1.narod.ru/cpp_new#12 to open article #12 etc)


---
[ 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: Fri Mar 09, 2007 5:42 am    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

In article <esojh4$9c6$1 (AT) aioe (DOT) org>, "Grizlyk" <grizlyk1 (AT) yandex (DOT) ru>
wrote:

Quote:
I can repeat again:

Sorry for making you repeat.

Quote:
if you will struggle with "compile time attributes", you
always will get warning about "undefined behaviour" and never will get the
warnings in opposite case of correct design. Coreect desing can be like
this:

A a1
if (foo())
{
A @a2(a1);
...
}

else
{

// Has a1 been moved from here?
A @a3(a1); // error or not?

}

Now all OK.

I'm not convinced that my original code was incorrect. The if clause
might have ended with:

throw_my_exception();

I know that this function is never going to return, thus the "else"
isn't needed. But the compiler has no way to know that short of whole
program analysis (which might have to be delayed until run time if
throw_my_exception() lives in a "plug-in".

Quote:
You must take in account, that "moveable" is specific and
_limited_ data type, as "const", we can not use limited type in free manner.
We can not write for example like this:

Hmm... so can't move from just any type? In generic code I would like
to move things around without knowing much about the type. Maybe
something like:

template <class It> It& increment(It&);

template <class It, class T>
It
foo(It first, It last, const T& x)
{
It i = first;
while (increment(i) != last)
{
if (!(*i == x))
{
*first = std::move(*i);
++first;
}
}
return first;
}

At the time I write this generic code, I don't know the type of *i, but
I want the code to treat *i as an rvalue because I know that I'll never
need the value stored at *i again. But I'm not sure how the compiler
will know that. To the compiler it may look like I'm moving from the
same lvalue over and over. Is my above example code:

1. A compile time error?
2. A warning about undefined behavior?
3. Not possible to express with your design?
4. Requires another keyword such as "runtime" that you mentioned?
5. Incorrect design?

If the answer is 4 (requires "runtime") I fear that much (most?) of the
code I write will require this keyword. If I have to nearly always
write "runtime" anyway I might get lulled into believing that my
double-move compile time errors are always just noisy false positives.

-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: Fri Mar 09, 2007 3:02 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

On Mar 8, 7:09 pm, "Grizlyk" <grizl...@yandex.ru> wrote:
Quote:

Fortunatelly to us, compiler easy can do "compile time testing" in most
_very_ important cases (as for auto_ptr(unique_ptr)). It is very important
becase we will be able to make good reliable replacement of "garbage
collector" _without_ any overhead.


You've said a couple of times 'auto_ptr(unique_ptr)' is an important
case. What are you talking about?

James

---
[ 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: Mon Mar 12, 2007 7:19 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

On Mar 12, 5:22 pm, jdenn...@acm.org (James Dennett) wrote:
Quote:
Grizlyk wrote:
tasjae...@gmail.com wrote:
Fortunatelly to us, compiler easy can do "compile time testing" in most
_very_ important cases (as for auto_ptr(unique_ptr)). It is very
important
becase we will be able to make good reliable replacement of "garbage
collector" _without_ any overhead.

You've said a couple of times 'auto_ptr(unique_ptr)' is an important
case. What are you talking about?

What does "couple of times 'auto_ptr(unique_ptr)'" mean?

You wrote "auto_ptr(unique_ptr)" more than once. The question
is what you meant by that, and what you see the issue as being
in this case? I'm guessing that you meant something like
"auto_ptr and/or unique_ptr" but it's not clear to me which
issue you are attempting to raise regarding those smart
pointers.


Yes, that's what I meant, thanks. It's my fault for using the
colloquial (and possibly just British?) 'couple'.


Quote:
-- James

(And I thought I'd also make it clear that I'm a different James,
since the name in my profile doesn't seem to come out in this group)

James Hopkin



---
[ 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
James Dennett
Guest





PostPosted: Mon Mar 12, 2007 10:22 pm    Post subject: Re: Constrained Forwarding(R-Value Reference) Reply with quote

Grizlyk wrote:
Quote:
tasjaevan (AT) gmail (DOT) com wrote:
Fortunatelly to us, compiler easy can do "compile time testing" in most
_very_ important cases (as for auto_ptr(unique_ptr)). It is very
important
becase we will be able to make good reliable replacement of "garbage
collector" _without_ any overhead.

You've said a couple of times 'auto_ptr(unique_ptr)' is an important
case. What are you talking about?

What does "couple of times 'auto_ptr(unique_ptr)'" mean?

You wrote "auto_ptr(unique_ptr)" more than once. The question
is what you meant by that, and what you see the issue as being
in this case? I'm guessing that you meant something like
"auto_ptr and/or unique_ptr" but it's not clear to me which
issue you are attempting to raise regarding those smart
pointers.

-- James

---
[ 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
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
 


Powered by phpBB © 2001, 2006 phpBB Group