Topic: Constrained Forwarding(R-Value Reference)
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Fri, 6 Apr 2007 21:30:59 CST Raw View
Howard Hinnant wrote:
>> I have written:
>>
>> >> There are differences between "rvalues", "movability" and "moveable
>> >> data type".
>>
>> Do you agree with the explanation?
>
> Except for rvalue, we have not established sufficiently clear and firm
> definitions of these terms to the extent I can either agree or disagree
> with your statement.
We have differences in _behaviour_ for each of them, so we need to
make sharp and clear names for each behaviour, and we need name for
each behaviour, so detected behaviour is sufficiently clear and firm
definition of each term.
And my question means: do you agree that we can see some different
behaviours for "move", and that "r-value reference" can not cover very
simple cases of algorithms with moveable data type.
>> I think, you can try to do the implementation yourself, and place here
>> result with all error points, that you have found. I have made some examples
>> with "moveable data type" here, but it is producing nonthing positive (just
>> have been ignored).
>
> Ok, here is my best attempt with your syntax/design:
>
> template <class FwdIt, class T>
> FwdIt
> remove(FwdIt first, FwdIt last, const T& value)
> {
> first = std::find(first, last, value);
> if (first != last)
> {
> FwdIt i = first;
> while (++i != last)
> {
> if (!(*i == value))
> {
> *first = *i;
> ++first;
> }
> }
> }
> return first;
> }
>
> But I believe you replied to this before with:
>
>> There is no one declaration of moveable classes here, only copyable, i can
>> not answer to the kind of question related to undeclared classes.
>
> I don't know where to put the movable declarations for the above generic
> algorithm either (using your design). I just know that I want the
> statement:
>
> *first = *i;
>
> to use move assignment if it is available, else use copy assignment.
It means you want to overload "operator=" as "move assignment" or as
"copy assignment" by template parameter declaration. You write below,
that
> However I believe using the syntax I am showing
>
> *first = *i;
>
> is extremely dangerous in generic code, even if the value_type is
> declared movable. The same algorithm might desire to both copy and move
> from value_types and having the same syntax for both operations seems
> error prone.
There are really two dangerous here:
a) if code support moveable, the code must be explicitly declared as
supported moveable
b) indirect data access, due to usage of iterator (pointer, wrapper
etc)
a) Any algorithm, designed to work with copyable, must be in general
case re-designed to work with moveable also. After that, we must tell
to compiler by declarations, that code is suitable to work with
moveable, for example like this:
template <test moveable class T>
class FwdIt;
template <test class FwdIt, test moveable class T>
FwdIt
remove(FwdIt first, FwdIt last, const moveable T& value);
Instead of "test" we can use "explicit" keyword.
b) Note, that many problems here can appear only due to indirect data
access - due to usage of iterator (pointer, wrapper etc) returning
pointer or reference to moveable. There are many cases when moveable
will be returned by value - there we will have no the problems.
Without iterators we could easy write the example:
class Z;
Z i;
moveable Z first;
//here "move assignment" will be used,
//because "first" declared as "moveable"
first = i;
//here "copy assignment" will be used,
//because "i" declared as "copyable".
i = first;
Also for the variables declared in the example we can use local
moveable/copyable type override with the help of:
a) explicit cast to more limited type:
static_cast<moveable T&:()>
tell to compiler to use "move assignment"
if "move assignment" declared, then must be public
if "move assignment" undeclared, then will be auto-generated
else
if "copy assignment" declared, then must be public
if "copy assignment" undeclared, then will be auto-generated
else
error
b) explicit cast to less limited type:
moveable_cast<T&>
tell to compiler to use "copy assignment"
if "copy assignment" declared, then must be public
if "copy assignment" undeclared, then will be auto-generated
else
error
c) binary explicit specialization
of "assignment by default" (operator=):
operator<-<
tell to compiler to use "move assignment"
by default similar to static_cast<moveable T&:()>,
but can be overloaded by user
operator<+<
tell to compiler to use "copy assignment"
by default similar to moveable_cast<T&>,
but can be overloaded by user
d) with "unary operators"
and copying intermediate value of Z::internal_state
"unary operator move"
operator<
operator<-<
tell to compiler to use "move to Z::internal_state"
operator=(operator<-<)
and then we can "assign from z::internal_state"
"unary operator copy"
operator<+<
tell to compiler to use "copy to Z::internal_state"
operator=(operator<+<)
and then we can "assign from z::internal_state"
Examples of the overriding:
a)
//"move assignment" for copyable
static_cast<moveable typeof(i)&:()>(i)=first;
//explicit "move assignment" for moveable
static_cast<moveable typeof(first)&:()>(first)=i;
b)
//"copy assignment" for moveable
moveable_cast<typeof(first)&>(first)=i;
//explicit "copy assignment" for copyable
moveable_cast<typeof(i)&>(i)=first;
c)
//by declaration of target variable
i = first;
first = i;
//binary operator move for copyable
i<-<first;
//binary operator move for moveable
first<-<i;
//binary operator copy for moveable
first<+<i;
//binary operator copy for copyable
i<+<first;
d)
//unary operator move for copyable
i=<first;
//unary operator move for moveable
first=<i;
//unary operator copy for moveable
first=<+<i;
//unary operator copy for copyable
i=<+<first;
So we can also tell to compiler by declaration inside implementation
of the "remove", that code is using "move assignment", at least to
help to read the code
*first <-< *i;
Let's consider that can be done with the indirect access in order to
do "overload "operator=" as "move assignment" or as "copy assignment"
by template parameter declaration".
1. The one way, we can use template parameter "FwdIt" similar to class
"moveable_iterator".
A. I am repeating the previous possible declaration of template
parameter "FwdIt" as class "moveable_iterator":
//moveable_iterator
template<class T=moveable_class>
class moveable_iterator
{
moveable T auto*:() data;
public:
//here "operator++" allow to do "<i++"
moveable moveable_iterator&:(ctor;...)
operator++ ()ctor;
moveable moveable_iterator
operator++ (const int)ctor;
//moveable reference without attributes
moveable T& operator* (){ return *data; }
//moveable reference without without explicit attributes
//by default means "the attributes can not be changed"
//moveable T&:(...;same)
//("move ctor" and "move assignment" is exception)
//operator move
moveable T::internal_state
operator< ()dtor { return <*data; }
public:
...
};
Take a look on "moveable_iterator::operator*()" declaration:
//moveable reference without attributes
moveable T& operator* (){ return *data; }
Its return value declared as "moveable T&" means you will not change
compile-time attributes of value of "moveable T" via the reference
returned by "moveable_iterator::operator*()".
The constness of compile-time attributes protect you from "move from"
or "move to" the return value of "moveable_iterator::operator*()". In
comparison with semantics of "auto_ptr" this means you will be
protected from ownership changement of "T".
Is the declaration the best or the worst for all possible cases in the
world i do not know, beacause syntax of "moveable data type" gives to
user general tools to free express all necessary properties of
moveable data type. This can be compared with declaration:
const T foo();
is "const T" good or bad? I do not know.
To see correct usage of operator* you cam compare the lines from
implementation of "remove":
//here "*i" has been used correctly.
if (!(*i == value))
//here "*i" and "*first" have been used incorrectly.
*first = *i;
B. By the way, you can declare attributes of return value of
"moveable_iterator::operator*()" to be "not worse than was". This
makes usage of "*first" (in the comparing above) quite correct:
//moveable reference without attributes
moveable T&:(...;!dtor) operator* (){ return *data; }
But in the case you can get async changement of attributes of "*data"
and iterator, so we are forced to make manual correctness of
attributes of iterator:
{
//assuming here "first" and "*first" are "dtor"
//assuming declared:
//"any_type T::operator=(any_modified_T)ctor;"
//ok due to !dtor of "moveable T&" declaration
*first = new T;
//here "*first" is "ctor", but "first" is still "dtor"
//error detected incorrectly
*first;
//we can force correctness of "first"
first:(ctor);
//ok
*first;
}
C. But you can not "move from" reference, returned from
"moveable_iterator::operator*()". The expression:
*first = *i;
is not the best expression to make movement from iterator or wrapper,
because using "operator*" to make move is wrong idea in general,
because (speaking auto_ptr's semantics) we need _two different
operations_ to separate "ownership transfer, move internal value" and
"return POD pointer, get internal value".
In the previous example unary operator move (operator<) has been used:
>> you must not use "operator*" instead "operator<" to make move.
>> There are differense between "get POD pointer" and "move ownership".
>>
>> Now you can be protected from double move for each step
>>
>> {
>> *first = <i;
>> //error detected
>> *i;
>>
>> ++first;
>> //ok
>> *i;
>> }
2. There are other ways, for example, we can use template parameter
"FwdIt" with operator* allowing movement and refusing from
declarations of control of "double-move error". Look at the changes of
"moveable_iterator":
//moveable_iterator
template<class T=moveable_class>
class moveable_iterator
{
public:
...
//moveable reference without attributes
moveable T&:(...;...) operator* (){ return *data; }
//moveable reference without without explicit attributes
//by default means "the attributes can not be changed"
//moveable T&:(...;same)
//( "ctor", "assignment", "binary move" and "binary copy"
// is exception and its attributes are ":(ctor;dtor)" )
//unary operator move
moveable T::internal_state
operator< ()dtor { return <*data; }
};
we are forced to make manual correctness of attributes of iterator:
{
*first <-< *i;
i:(dtor);
//error detected
*i;
++first;
//ok
*i;
}
> In the current rvalue reference proposal, the desire to prefer move else
> copy is stated with the following syntax:
>
> template <class FwdIt, class T>
> FwdIt
> remove(FwdIt first, FwdIt last, const T& value)
> {
> first = std::find(first, last, value);
> if (first != last)
> {
> FwdIt i = first;
> while (++i != last)
> {
> if (!(*i == value))
> {
> *first = std::move(*i);
> ++first;
> }
> }
> }
> return first;
> }
>
> Now the author of the algorithm is clearly aware that *i may be moved
> from (this is not an accidental move).
>
> So I ask again: How would you implement std::remove? Please show with
> a full code example rather than bits of code interspersed with prose.
> My apologies in advance if you've already shown the implementation of
> std::remove. I respectfully request you repost it.
There are two ways of implementation of "std::remove", that first came
up to my mind. Note, the concrete way of implementation can depend
from conventions of concrete library for interface of iterators and so
on:
1. ======
//required interface of "T"
//
class T
{
//moveable
public:
T(const moveable T&);
moveable T& operator= (const moveable T&)ctor;
};
//required interface of "FwdIt"
//
template <test moveable class T>
class FwdIt
{
protected:
moveable T auto*:()
data();
const moveable T auto*:()
data() const;
//data access
public:
//operator access
moveable T &:(...;!dtor)
operator* (){ return *data(); }
const moveable T &:(...;!dtor)
operator* ()const { return *data(); }
//operator access
moveable T auto*:(...;!dtor)
operator-> (){ return data(); }
const moveable T auto*:(...;!dtor)
operator-> ()const { return data(); }
//operator unary move
moveable T
operator< ()const dtor { return *data(); }
//walking over container
public:
FwdIt &:(ctor;...)
operator++ ()ctor;
FwdIt
operator++ (const int)ctor;
char operator ==(const FwdIt&)const;
char operator !=(const FwdIt&)const;
//copyable
public:
//copy attributes from src
FwdIt(const FwdIt& src) copy(src);
FwdIt& operator= (const FwdIt& src) copy(src);
};
//implementation of remove
//
template <test class FwdIt, test moveable class T>
FwdIt
remove(FwdIt first, FwdIt last, const moveable T& value)
{
first = std::find(first, last, value);
if (first != last)
{
FwdIt i=first;
while (++i != last)
{
if (!(*i == value))
{
*first = <i;
++first;
}
}
}
return first;
}
2. ======
//required interface of "T"
//
class T
{
//moveable
public:
T(const moveable T&);
moveable T& operator= (const moveable T&)ctor;
};
//required interface of "FwdIt"
//
template <test moveable class T>
class FwdIt
{
protected:
moveable T auto*:()
data();
const moveable T auto*:()
data() const;
//data access
public:
//operator access
moveable T &:(...;...)
operator* (){ return *data(); }
const moveable T &:(...;...)
operator* ()const { return *data(); }
//operator access
moveable T auto*:(...;...)
operator-> (){ return data(); }
const moveable T auto*:(...;...)
operator-> ()const { return data(); }
//walking over container
public:
FwdIt &:(ctor;...)
operator++ ()ctor;
FwdIt
operator++ (const int)ctor;
char operator ==(const FwdIt&)const;
char operator !=(const FwdIt&)const;
//copyable
public:
//copy attributes from src
FwdIt(const FwdIt& src) copy(src);
FwdIt& operator= (const FwdIt& src) copy(src);
};
//implementation of remove
//
template <test class FwdIt, test moveable class T>
FwdIt
remove(FwdIt first, FwdIt last, const moveable T& value)
{
first = std::find(first, last, value);
if (first != last)
{
FwdIt i=first;
while (++i != last)
{
if (!(*i == value))
{
*first <-< *i;
i:(dtor);
++first;
}
}
}
return first;
}
It is evidently, that the example can be implemented with the help of
"moveable concept" proposal. Take a look to my page http://grizlyk1.narod.ru/cpp_new,
for changed article #11, #14_1 .. #14_3 (last has been created at
last) and other changes.
--
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 ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 7 Apr 2007 17:21:23 GMT Raw View
on Fri Apr 06 2007, "Grizlyk" <grizlyk1-AT-yandex.ru> wrote:
> Also for the variables declared in the example we can use local
> moveable/copyable type override with the help of:
>
> a) explicit cast to more limited type:
> static_cast<moveable T&:()>
> tell to compiler to use "move assignment"
> if "move assignment" declared, then must be public
> if "move assignment" undeclared, then will be auto-generated
> else
> if "copy assignment" declared, then must be public
> if "copy assignment" undeclared, then will be auto-generated
> else
> error
The above is highly ambiguous and probably nonsensical. If read
according to the usual rules for if/then/else, it would be parsed as
if "move assignment" declared,
then must be public
if "move assignment" undeclared,
then will be auto-generated
else
if "copy assignment" declared,
then must be public
if "copy assignment" undeclared,
then will be auto-generated
else
error
But that would be needlessly complex, because '"move assignment"
declared' and '"move assignment" undeclared' are mutually exclusive.
It "simplifies" (if you can call it that) to:
if "move assignment" declared,
then must be public
if "copy assignment" declared,
then must be public
else
"move assignment" will be auto-generated
if "copy assignment" undeclared,
then will be auto-generated
else
error
which seems to say that "tell the compiler to use move assignment"
always generates a copy assignment if none declared, and if one is
declared requires it to be public. I can't imagine that's really what
you meant.
Much more likely, the first "else" was supposed to balance the two pairs of
"if" clauses somehow:
tell to compiler to use "move assignment"
(
if "move assignment" declared, then must be public
if "move assignment" undeclared, then will be auto-generated
)
else
(
if "copy assignment" declared, then must be public
if "copy assignment" undeclared, then will be auto-generated
)
else
error
But that makes even less sense, because there's no outer "if"
condition to go with the first "else."
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
Don't Miss BoostCon 2007! ==> http://www.boostcon.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.comeaucomputing.com/csc/faq.html ]
Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Sat, 24 Mar 2007 02:22:51 CST Raw View
On Mar 23, 3:32 pm, tasjae...@gmail.com wrote:
> The other question I skimmed over is about how to deal with a mutable
> range being represented by a const pair.
>
> Can I provide a concept_map for both const and non-const pairs?
>
> template <Iterator Iter>
> concept_map MutableRange<pair<Iter, Iter>> {}
>
> template <Iterator Iter>
> concept_map MutableRange<const pair<Iter, Iter>> {}
Yes, absolutely.
Cheers,
Doug
---
[ 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 ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 21 Mar 2007 16:56:33 GMT Raw View
on Thu Feb 15 2007, pongba-AT-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:
>
> 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?
I noticed that nobody seems to have answered your original question.
IIRC, we considered this class of cases and our first conclusion was
that we weren't sure there was a real use case for constrained
forwarding (do you have one)?
If I found a real use case, I'd apply enable_if
(http://www.boost.org/libs/utility/enable_if.html) or, better, concept
constraints
(http://www.generic-programming.org/languages/conceptcpp/), which is
much more general than constraining the arguments based on the mere
spellings of their types (i.e. "is the argument a specialization of
the MyC template?").
HTH,
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Wed, 21 Mar 2007 17:16:44 GMT Raw View
Howard Hinnant wrote:
>
>> The "r-value reference" never can replace ordinary moveable data type (
>> "r-value reference" is just limited subset of correct moveable data type
>> and
>> "r-value reference" has special rules to interacts with copyable, the
>> rules
>> does not defined by class declaration ) because with the help of "r-value
>> reference" user never will be able to express simplest kind of algorithms
>> with moveable data type.
>
> I would be interested in your implementation of std::remove (from
> <algorithm>).
I think, you can try to do the implementation yourself, and place here
result with all error points, that you have found. I have made some examples
with "moveable data type" here, but it is producing nonthing positive (just
have been ignored).
If you can show concrete places of code, where "moveable data type" can not
be used - just do it. I do not know the places.
But i am ready to show (and have done it several times), that "r-value
reference" can not help us to implement _simplest_ algorithms working with
"conceptual moveable" data.
> I'm looking for something that will work when the value_type has only a
> copy constructor/assignment (e.g. complex<double>), when the value_type
> has both copy and move constructors/assignments, e.g. string (and move
> is preferred for performance reasons), and when the value_type has
> disabled (private) copy semantics but public move members (like the
> proposed unique_ptr).
>
> It is not clear to me if this will require 1, 2 or 3 generic functions,
> exactly what (if anything) has to be declared movable and/or const,
It is not easy to see what you meant, write code to show the unsuitable
places.
By words, we no need three generic functions for each behaviour. If
algorithm can work with moveable, the algorithm _must_ declare parameters,
result and variables as "moveable". The copyable data also can work with the
algorithm, but opposite is incorrect.
> and if any other keywords will be needed to disable compile-time
> double move detection.
I do not know what do you meant. I have shown in the thread example of code,
that even with pointers we do not need any runtime-conditions, you just
ignore the example. What is wrong in the example?
I have written:
>> There are differences between "rvalues", "movability" and "moveable
>> data type".
Do you agree with the explanation?
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Wed, 21 Mar 2007 18:19:48 GMT Raw View
James Dennett wrote:
>
>>>>>> He has asked me how it can be implemented with my proposal. Try open
>>>>>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue".
>>>>>> Really,
>>>>>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>>>>>> "Lvalue" means "address can be taken" and nothing more.
>>>>>> "Lvalue" is unrelated to "const", "copyable" or "moveable" data type.
>>>>>>
>>>>> The relationship is something that exists and has been
>>>>> considered in quite a lot of detail.
>>
>> As I can understand, you have said, that term "relationship" must be
>> applied
>> to bind "Lvalue" and "const", because of either something exist or
>> something
>> can be considered in quite a lot of detail.
>
> You misstate me. The fact that the relationship has
> been discussed
has been? Who has said "has been"? Take a look:
>> can be considered.
> in much detail, and that the details
> are significant, specific and reasonable, is very,
> very strong evidence for its existence. If you wish
> to claim, in spite of such evidence, that there is no
> connection, you need to refute this somehow.
>
>> Then i have said, that
>>
>>>> Any term, binding several objects, as relationship do, of course can be
>>>> considered for any combinations of any objects.
>>
>> So we always can consider any term, binding several objects, and consider
>> in
>> quite a lot of detail.
>
> That is not true; if there is no significant relationship,
> there is no significant detail to consider.
In order to realize "is any significant value or not" you must make
consideration, so we always can consider any term, binding several objects.
>>>> For example, we can consider
>>>> question about any relationships between C++ and rain in any desert.
>>> But we would not reasonably be able to consider it
>>> "in detail", as there is no significant relationship
>>> between C++ and weather in some specified geographical
>>> region.
>>
>> It does not matter here "reasonably" or not, it is only important that we
>> can do consider any term, binding any several objects.
>
> Reasonableness is very important.
Reasonableness is important, but can not ne found befor process of
consideration is started. We can not detect reasonableness befor
consideration, so unknown value of reasonableness can not be obstacle to
process of consideration.
> If you do not consider
> reasonableness as a crucial factor in discussions, it is
> unlikely that your discussions will be fruitful.
>
>>>> But the possible ability of consideration is not the same, that the
>>>> considered term can be applied to binding the concrete combination of
>>>> the
>>>> concrete objects.
>>
>> So I have said, that in spite of the fact, that we always can consider
>> any
>> term, the existence of process of consideration is not the same, that the
>> considered term must be applied to binding the concrete combination of
>> the
>> concrete objects.
>>
>> If we have found after consideration process, that relationship is not
>> exist
>> (objects unrelated), we can continue to apply the term "relationship" in
>> the
>> form of "has no relationship" (unrelated).
>
> That would be most unhelpful. It is not consistent to say
> that there is a relationship and that the items have no
> relationship.
There are two things with the same name "relationship": "relationship" is "a
kind of binding" and "relationship" is value of "the kind of binding".
> This is a self-contradictory use of
> terminology, which is why precision in terminology is
> vital in these discussions.
>
>>>> For example, there are no any relationship between C++
>>>> and rain in any desert.
>>> Right, so that would not be a useful thing for us to
>>> discuss.
>>
>> So you have agreed with me, that "Lvalue" can be as well related (has
>> relationship) as unrelated (has no relationship) to "const", "copyable"
>> or
>> "moveable" data type.
>
> That is untrue. I do not agree with that, and I have
> never stated anything to suggest that I do.
It looks like you want to disagree with me even in spite of own words.
>> It does not matter either can "relationship of
>> "Lvalue" and "const" has been considered in quite a lot of detail" or can
>> not in order to be able to apply "relationship" term to bind "Lvalue" and
>> "const".
>
> This "argument" does not seem to be based on logic.
Logic also based on the condition, that all participants follow desire to
find result, truth, using true ways tod search, else we just need police
instead of logic.
>>>> So original sentence: "there are no any relationship between "Lvalue"
>>>> and
>>>> "const", "copyable" or "moveable" data type" is correct statement at
>>>> least
>>>> formally.
>>> How can it be correct
>>
>> _formally_ it is always correct, because you have agreed with me, that
>> "Lvalue" can be as well related as unrelated to "const", "copyable" or
>> "moveable" data type.
>
> I have not agreed with you, and it is not correct.
It looks like you want to disagree with me even in spite of own words.
> Again, a false premise (that I have agreed with you)
> leads to a false conclusion (that your statement
> was factually correct). Reasoning from valid
> premises, using logic, will be much more likely
> to avoid reaching false conclusions.
>
>>> when others have supplied specific
>>> details of the concrete relationship that exists between
>>> rvalues and movability?
>>
>> As i can guess, you does not agree with concrete _form of relationship_:
>> i
>> think "unrelated", you think "related".
>
> If there is a relationship, they are related. This is what
> the words mean in English.
This is international semantics of "relationship" and the following sentence
is correct: "no relationship (unrelated)" value of "relationship" bind.
--
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 ]
Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Wed, 21 Mar 2007 19:49:36 GMT Raw View
In article <etroof$jn5$1@aioe.org>, grizlyk1@yandex.ru ("Grizlyk")=20
wrote:
> I have written:
>=20
> >> There are differences between "rvalues", "movability" and "moveable
> >> data type".
>=20
> Do you agree with the explanation?
Except for rvalue, we have not established sufficiently clear and firm=20
definitions of these terms to the extent I can either agree or disagree=20
with your statement.
> I think, you can try to do the implementation yourself, and place here=20
> result with all error points, that you have found. I have made some exa=
mples=20
> with "moveable data type" here, but it is producing nonthing positive (=
just=20
> have been ignored).
Ok, here is my best attempt with your syntax/design:
template <class FwdIt, class T>=20
FwdIt=20
remove(FwdIt first, FwdIt last, const T& value)=20
{=20
=A0 =A0 first =3D std::find(first, last, value);=20
=A0 =A0 if (first !=3D last)=20
=A0 =A0 {=20
=A0 =A0 =A0 =A0 FwdIt i =3D first;=20
=A0 =A0 =A0 =A0 while (++i !=3D last)=20
=A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 if (!(*i =3D=3D value))=20
=A0 =A0 =A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *first =3D *i;=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++first;=20
=A0 =A0 =A0 =A0 =A0 =A0 }=20
=A0 =A0 =A0 =A0 }=20
=A0 =A0 }=20
=A0 =A0 return first;=20
}=20
But I believe you replied to this before with:
> There is no one declaration of moveable classes here, only copyable, i =
can=20
> not answer to the kind of question related to undeclared classes.
I don't know where to put the movable declarations for the above generic=20
algorithm either (using your design). I just know that I want the=20
statement:
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *first =3D *i;=20
to use move assignment if it is available, else use copy assignment. =20
If I have to guess further, I might be tempted to bring in ideas from=20
the concepts proposal:
template <class FwdIt, class T>
where {Movable(iterator_traits<FwdIt>::value_type)}
FwdIt=20
remove(FwdIt first, FwdIt last, const T& value)=20
{=20
=A0 =A0 first =3D std::find(first, last, value);=20
=A0 =A0 if (first !=3D last)=20
=A0 =A0 {=20
=A0 =A0 =A0 =A0 FwdIt i =3D first;=20
=A0 =A0 =A0 =A0 while (++i !=3D last)=20
=A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 if (!(*i =3D=3D value))=20
=A0 =A0 =A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *first =3D *i;=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++first;=20
=A0 =A0 =A0 =A0 =A0 =A0 }=20
=A0 =A0 =A0 =A0 }=20
=A0 =A0 }=20
=A0 =A0 return first;=20
}
However I believe using the syntax I am showing
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *first =3D *i;=20
is extremely dangerous in generic code, even if the value_type is=20
declared movable. The same algorithm might desire to both copy and move=20
from value_types and having the same syntax for both operations seems=20
error prone.
In the current rvalue reference proposal, the desire to prefer move else=20
copy is stated with the following syntax:
template <class FwdIt, class T>=20
FwdIt=20
remove(FwdIt first, FwdIt last, const T& value)=20
{=20
=A0 =A0 first =3D std::find(first, last, value);=20
=A0 =A0 if (first !=3D last)=20
=A0 =A0 {=20
=A0 =A0 =A0 =A0 FwdIt i =3D first;=20
=A0 =A0 =A0 =A0 while (++i !=3D last)=20
=A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 if (!(*i =3D=3D value))=20
=A0 =A0 =A0 =A0 =A0 =A0 {=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *first =3D std::move(*i);=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ++first;=20
=A0 =A0 =A0 =A0 =A0 =A0 }=20
=A0 =A0 =A0 =A0 }=20
=A0 =A0 }=20
=A0 =A0 return first;=20
}=20
Now the author of the algorithm is clearly aware that *i may be moved=20
from (this is not an accidental move).
So I ask again: How would you implement std::remove? Please show with=20
a full code example rather than bits of code interspersed with prose. =20
My apologies in advance if you've already shown the implementation of=20
std::remove. I respectfully request you repost it.
-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 ]
Author: jdennett@acm.org (James Dennett)
Date: Thu, 22 Mar 2007 04:57:20 GMT Raw View
Grizlyk wrote:
> James Dennett wrote:
>>>>>>> He has asked me how it can be implemented with my proposal. Try open
>>>>>>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue".
>>>>>>> Really,
>>>>>>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>>>>>>> "Lvalue" means "address can be taken" and nothing more.
>>>>>>> "Lvalue" is unrelated to "const", "copyable" or "moveable" data type.
>>>>>>>
>>>>>> The relationship is something that exists and has been
>>>>>> considered in quite a lot of detail.
>>> As I can understand, you have said, that term "relationship" must be
>>> applied
>>> to bind "Lvalue" and "const", because of either something exist or
>>> something
>>> can be considered in quite a lot of detail.
>> You misstate me. The fact that the relationship has
>> been discussed
>
> has been? Who has said "has been"? Take a look:
>>> can be considered.
It's above, in the material you quoted: look up there,
"has been considered in quite a lot of detail". Much
of that consideration and discussion has been in public;
there should be no reason to question whether it has
happened. It has, demonstrably so.
>> in much detail, and that the details
>> are significant, specific and reasonable, is very,
>> very strong evidence for its existence. If you wish
>> to claim, in spite of such evidence, that there is no
>> connection, you need to refute this somehow.
>>
>>> Then i have said, that
>>>
>>>>> Any term, binding several objects, as relationship do, of course can be
>>>>> considered for any combinations of any objects.
>>> So we always can consider any term, binding several objects, and consider
>>> in
>>> quite a lot of detail.
>> That is not true; if there is no significant relationship,
>> there is no significant detail to consider.
>
> In order to realize "is any significant value or not" you must make
> consideration, so we always can consider any term, binding several objects.
By addressing only fragments of this, your argument is
incomplete to the point of being without utility. The
observation on significance is based on what can be (or
is) discussed. Your argument is based on false
assumptions, again, and reaches false conclusions.
>>>>> For example, we can consider
>>>>> question about any relationships between C++ and rain in any desert.
>>>> But we would not reasonably be able to consider it
>>>> "in detail", as there is no significant relationship
>>>> between C++ and weather in some specified geographical
>>>> region.
>>> It does not matter here "reasonably" or not, it is only important that we
>>> can do consider any term, binding any several objects.
>> Reasonableness is very important.
>
> Reasonableness is important, but can not ne found befor process of
> consideration is started. We can not detect reasonableness befor
> consideration, so unknown value of reasonableness can not be obstacle to
> process of consideration.
Entirely wrong; the fact that there is nothing reasonable
to consider will prevent significant meaningful discussion.
(In other words: you cannot have significant meaningful
discussion if there is nothing reasonable to discuss.)
>> If you do not consider
>> reasonableness as a crucial factor in discussions, it is
>> unlikely that your discussions will be fruitful.
>>
>>>>> But the possible ability of consideration is not the same, that the
>>>>> considered term can be applied to binding the concrete combination of
>>>>> the
>>>>> concrete objects.
>>> So I have said, that in spite of the fact, that we always can consider
>>> any
>>> term, the existence of process of consideration is not the same, that the
>>> considered term must be applied to binding the concrete combination of
>>> the
>>> concrete objects.
>>>
>>> If we have found after consideration process, that relationship is not
>>> exist
>>> (objects unrelated), we can continue to apply the term "relationship" in
>>> the
>>> form of "has no relationship" (unrelated).
>> That would be most unhelpful. It is not consistent to say
>> that there is a relationship and that the items have no
>> relationship.
>
> There are two things with the same name "relationship": "relationship" is "a
> kind of binding" and "relationship" is value of "the kind of binding".
Sticking to the one reasonable definition in a given context
will help, though it doesn't matter in this case: you claimed
there was no relationship. By my argument, that's false as
there is a significant, meaningful relationship that has been
discussed, publicly, in some depth. By your argument, it is
false tautologically (as even "has no relationship" would
mean that there is a relationship). But anyway; this isn't
very interesting, except as an example of something you
wrote that is hard to refute because it seems to make no
real sense, and to be obviously false in as much as it can
be said to make sense.
>> This is a self-contradictory use of
>> terminology, which is why precision in terminology is
>> vital in these discussions.
>>
>>>>> For example, there are no any relationship between C++
>>>>> and rain in any desert.
>>>> Right, so that would not be a useful thing for us to
>>>> discuss.
>>> So you have agreed with me, that "Lvalue" can be as well related (has
>>> relationship) as unrelated (has no relationship) to "const", "copyable"
>>> or
>>> "moveable" data type.
>> That is untrue. I do not agree with that, and I have
>> never stated anything to suggest that I do.
>
> It looks like you want to disagree with me even in spite of own words.
No; my words are consistent, and if you quote them
accurately you will find nothing else. It is possible
that you misunderstand them, in which case I would be
pleased to clarify, if you can state (in a way that I,
in turn, can understand) what needs to be clearer.
>>> It does not matter either can "relationship of
>>> "Lvalue" and "const" has been considered in quite a lot of detail" or can
>>> not in order to be able to apply "relationship" term to bind "Lvalue" and
>>> "const".
>> This "argument" does not seem to be based on logic.
>
> Logic also based on the condition, that all participants follow desire to
> find result, truth, using true ways tod search, else we just need police
> instead of logic.
It's an accepted standard in this forum that we assume
that participants are seeking truth in reasonable and
logical ways. We have a moderation panel in lieu of
police in case things go wrong; usually it has little
to do as participants do tend to act in good faith.
>>>>> So original sentence: "there are no any relationship between "Lvalue"
>>>>> and
>>>>> "const", "copyable" or "moveable" data type" is correct statement at
>>>>> least
>>>>> formally.
>>>> How can it be correct
>>> _formally_ it is always correct, because you have agreed with me, that
>>> "Lvalue" can be as well related as unrelated to "const", "copyable" or
>>> "moveable" data type.
>> I have not agreed with you, and it is not correct.
>
> It looks like you want to disagree with me even in spite of own words.
You say that twice, but provide no evidence. Again, it
is possible that you have misunderstood my meaning. In
this case, you could maybe succinctly state
(1) What your claim is, and
(2) What words of mine you think say that I agree with
the claim.
>> Again, a false premise (that I have agreed with you)
>> leads to a false conclusion (that your statement
>> was factually correct). Reasoning from valid
>> premises, using logic, will be much more likely
>> to avoid reaching false conclusions.
>>
>>>> when others have supplied specific
>>>> details of the concrete relationship that exists between
>>>> rvalues and movability?
>>> As i can guess, you does not agree with concrete _form of relationship_:
>>> i
>>> think "unrelated", you think "related".
>> If there is a relationship, they are related. This is what
>> the words mean in English.
>
> This is international semantics of "relationship" and the following sentence
> is correct: "no relationship (unrelated)" value of "relationship" bind.
I'm afraid that
"no relationship (unrelated)" value of "relationship" bind.
is not a sentence in English, so it cannot be correct.
Unfortunately, in this thread I am spending all my time in
trying to understand your English, or to make sense of what
appear to be false statements and contradictions, rather
than having a useful technical discussion. As this does
not seem to be helping, unless there is a change, I think
I will have to conclude that I cannot serve any useful
purpose in this discussion. It's regrettable that this
is not proving constructive, but I wish you well in your
sincere attempts to contribute to the C++ community.
-- 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 ]
Author: tasjaevan@gmail.com
Date: Thu, 22 Mar 2007 10:13:53 CST Raw View
On Mar 21, 4:56 pm, d...@boost-consulting.com (David Abrahams) wrote:
> > 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?
>
> I noticed that nobody seems to have answered your original question.
> IIRC, we considered this class of cases and our first conclusion was
> that we weren't sure there was a real use case for constrained
> forwarding (do you have one)?
>
I have a closely related example, although it isn't forwarding as
such. I'm unsure what the right solution is, using rvalue references
and concepts.
The example involves a MutableRange concept:
concept MutableRange<typename R>
{
typename iterator_type;
where Iterator<iterator_type>;
typename value_type = iterator_type::value_type;
iterator_type begin(R&);
iterator_type end(R&);
}
Key to the example is that MutableRange is modeled by both
containers (the container will usually be an lvalue, and must be non-
const)
pairs of iterators (the pair may be an rvalue)
amongst other things. (Allowing the pair of iterators to be const
seems to introduce additional issues, so I've ignored that for the
moment)
A function operating on a MutableRange will therefore be declared:
template <MutableRange R>
void f(R&&);
(Aside: unlike with forwarding, it doesn't matter whether R is deduced
to be a reference, because I don't think the identifier R will need to
be used explicitly in the implementation of such functions)
This function is already a constrained template, but I'd like to
restrain it some more. I'd like my function to take ranges of ints
only, for example.
If I've got the syntax right (it's on the edge of my understanding), I
think it can be kludged as follows:
concept IntOnly<typename T> {}
concept_map IntOnly<int> {}
concept MutableRangeOfInts : MutableRange
{
where IntOnly<value_type>;
}
template <MutableRangeOfInts R>
void f(R&&);
Is this correct and is there a better way of doing it?
Thanks
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 ]
Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Thu, 22 Mar 2007 15:45:01 CST Raw View
On Mar 22, 12:13 pm, tasjae...@gmail.com wrote:
> A function operating on a MutableRange will therefore be declared:
>
> template <MutableRange R>
> void f(R&&);
>
> (Aside: unlike withforwarding, it doesn't matter whether R is deduced
> to be areference, because I don't think the identifier R will need to
> be used explicitly in the implementation of such functions)
>
> This function is already aconstrainedtemplate, but I'd like to
> restrain it some more. I'd like my function to take ranges of ints
> only, for example.
>
> If I've got the syntax right (it's on the edge of my understanding), I
> think it can be kludged as follows:
>
> concept IntOnly<typename T> {}
> concept_map IntOnly<int> {}
>
> concept MutableRangeOfInts : MutableRange
> {
> where IntOnly<value_type>;
> }
Just a minor omission: you'll need concept parameters for the
MutableRangeOfInts concept. It should read:
concept MutableRangeOfInts<typename T> : MutableRange<T>
{
where IntOnly<value_type>
}
> template <MutableRangeOfInts R>
> void f(R&&);
>
> Is this correct and is there a better way of doing it?
Yes and yes.
You could also write f like this:
template<MutableRange R> where IntOnly<R::value_type>
void f(R&&);
Or, if you really want the value_type to be *exactly* int, rather than
anything that has a concept map for IntOnly, write:
template<MutableRange R> where std::SameType<R::value_type, int>
void f(R&&);
`
Cheers,
Doug
---
[ 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 ]
Author: tasjaevan@gmail.com
Date: Fri, 23 Mar 2007 13:32:45 CST Raw View
On Mar 22, 9:45 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:
>
> You could also write f like this:
>
> template<MutableRange R> where IntOnly<R::value_type>
> void f(R&&);
>
> Or, if you really want the value_type to be *exactly* int, rather than
> anything that has a concept map for IntOnly, write:
>
> template<MutableRange R> where std::SameType<R::value_type, int>
> void f(R&&);
Great, thanks. I'd forgotten you can have multi-type concepts.
The other question I skimmed over is about how to deal with a mutable
range being represented by a const pair.
Can I provide a concept_map for both const and non-const pairs?
template <Iterator Iter>
concept_map MutableRange<pair<Iter, Iter>> {}
template <Iterator Iter>
concept_map MutableRange<const pair<Iter, Iter>> {}
Thanks
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 ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Mar 2007 04:00:49 GMT Raw View
on Wed Mar 14 2007, "Grizlyk" <grizlyk1-AT-yandex.ru> wrote:
> tasjaevan@gmail.com wrote:
>>>
>>> Can you give me examples of any other possible values of the
>>> expression "auto_ptr(unique_ptr)" in the context: "in most _very_
>>> important cases (as for auto_ptr(unique_ptr))". I do not insist,
>>> it is just interesting why "guess" is required here.
>>>
>>
>> I read it as pseudo-C++. I thought you were talking about some kind
>> of conversion between the two types.
>
> As I can understand, auto_ptr with move semantics was called
> "unique_ptr", but really they do the same.
Not exactly the same, or, as you say, we wouldn't need a new name.
The differences in behavior would cause old, working, code to break if
auto_ptr were simply changed to use unique_ptr semantics.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Mar 2007 04:00:50 GMT Raw View
James Dennett wrote:
>
>>>> As I can understand, auto_ptr with move semantics was called
>>>> "unique_ptr", but really they do the same. So do we need new
>>>> name for auto_ptr? I think no.
>>>> ...
>>>> ( i already have listed 6 points of deisagreement with
>>>> the "r-value reference" in the thread and still no one has
>>>> denied my reasons in essence and proved that i was wrong ).
>>>>
>>> Your first point was:
>>>
>>>> 1. No auto_ptr support.
>>>> =======================
>>> And I've reread that point several times. I'm still failing
>>> to see how the rvalue reference package is lacking in this area.
>>
>> In general. if anyone really want find answer (unknown to him), I think,
>> he
>> is forced to answer on _each_ opposite argument in essence. There are no
>> other way of searching (at least i do not know other way).
> By and large, I can say that I could not make any sense
> of most of what you wrote.
In comp.lang.c++ one man have told me, that it is not a good idea to discuss
"the ways of correct discussions" mixed with topic. Maybe he was right, but
only if his opinion is not obstacle to find topic's answers.
I see ( looking on your reply "I can say that I could not make any sense of
most of what you wrote" ) my sentence "he is forced to answer on _each_
opposite argument in essence" has not found a good place in your sole.
I do not care do you agree with me or not, because the my sentence "he is
forced ..." is just translation of well-known rule of formal logic. As
programmer, if you will ignore any rules of formal logic in your programs,
your programs will never do any useful, because to CPU you never can say
"Listen, hell's CPU, I could not make any sense of most of what you doing".
During conversation it is the same, no any useful answer can be found with
refusing from rules of of formal logic, the only useful example of
conversation without the rules of formal logic is one containing no words,
only series of useless curses to address of enemies on square meeting,
producing loud "huraaa" from listeners.
In the my text above I am speaking, that your idea "I can say that I could
not make any sense of most of what you wrote" chiefly pointed against the
rule "he is forced to answer on _each_ opposite argument in essence" rather
than against me or my statements, because in order to disagree with me you
have violated the rule twice:
- did not list concrete error points in my text,
- implicitly said, that point of "misunderstands" is my bad source, not the
rule violation.
It is no any sense to discuss concrete problems without the rules of formal
logic. Also, i can explain the rule in the concrete case of conversation: I
never can guess what part of my statements has been wrong for you, and your
attempts to avoid concrete enumerating at least some of concrete wrong
points in my statemets often can speak that there are no wrong points there,
but you do not agree, so you are forced to search other way of "discussion".
> If so, it will not help to ask them what they "rejected",
> except for the fact that your objections did not seem
> coherent.
I understand: "I do not like it, I can not say why, but probably all are
totally non-coherent, because < here can be any unrelated to provement of
object of discussion >".
> Maybe I can address them somewhat:
>
> 1) "No auto_ptr support"
>
> It wasn't clear what you meant here.
>
Answer to concrete unclear sentences from original post.
> 2) "No ordered definitions
> for "copyable" and "moveable" C++ concepts.
>
> It was not clear what you meant by this, or why you felt
Answer to concrete unclear sentences from original post.
> 3. "Value" is not the same as "reference"
>
> It was not clear what you meant here.
Answer to concrete unclear sentences from original post.
> It's obviously true
> that "value" is not the same as "reference", but that does
> not present a problem for the proposal
I have no problem, so you are wrong.
> 4. "Non-const" is not the same as "moveable".
>
> Again, this is well-known, and not a problem for the
> proposal.
I have no problem, so you are wrong.
> If you believe there is a problem, you will
> need to provide convincing evidence.
http://grizlyk1.narod.ru/cpp_new/#12
> You write that
> "The ownership from auto_ptr can not be transferred
> more than one time" but this is not true; ownership
> can be passed along an unlimited chain of auto_ptr
> objects. Was this maybe not what you meant to write?
The ownership from _concrete object of class of_ auto_ptr can not be
transferred more than once. And context is clear speaking about it :
"Also it is easy to see, that non-const can not protect us from logically
wrong "operator move" has been applied twice to the non-const object (double
move). We can say, that move semantic required from C++ "once" support
rather than "non-const" support, it is really different things."
> This was also a key point in your number 5, which also
> says (incorrectly) that auto_ptr must not be passed by
> reference. Certainly passing auto_ptr by reference is
> unusual, but it can be quite correct.
http://grizlyk1.narod.ru/cpp_new/#11
"Also it means, that there are no more than one auto_ptr with the same
address simultaneously.
Unlike to auto_ptr, we can have many POD pointers with the same address
(that have been placed in an auto_ptr) and we can use the pointers while the
auto_ptr exist."
> 6. Interaction "copyable" and "moveable"
>
> Again, it was not clear what you meant here;
Answer to concrete unclear sentences from original post.
> could you be more explicit?
http://grizlyk1.narod.ru/cpp_new/#14
"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 (enumerate) all strict rules also ("functions
expecting moveable value can use copyable value" and so on). "
> It's possible that these problems are mine, but in general
> I find discussions on comp.std.c++ quite easy to follow
> (sometimes with a little work), so it's likely that if I
> do not see what points you are trying to make then there
> may be others who need more clarity.
>
> I cannot make constructive responses to most of your points
It is a pity, but i can not response instead of you.
> as they seem not to address the rvalue references subject.
Becasue r-value reference is implementation of something, so i am speaking
about the thing, the r-value reference is implementing.
> If you can express your ideas in more concrete detail, showing
> how they actually present difficulties with the current
> proposals in practical situations, you may well find that
> others will support your points.
Answer to concrete unclear sentences from original post, unrelated to the
current
proposals of r-value reference in practical situations.
So, as funny result of the discussion - to be happy is much better to be
unhappy. Speaking seriously, I have made the long explanation in the post in
order to make example and to refer on the example in future, if it will be
nessesary.
--
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 ]
Author: kuyper@wizard.net
Date: Mon, 19 Mar 2007 23:01:39 CST Raw View
"Grizlyk" wrote:
> James Dennett wrote:
.
> > By and large, I can say that I could not make any sense
> > of most of what you wrote.
>
> In comp.lang.c++ one man have told me, that it is not a good idea to discuss
> "the ways of correct discussions" mixed with topic. Maybe he was right, but
> only if his opinion is not obstacle to find topic's answers.
>
> I see ( looking on your reply "I can say that I could not make any sense of
> most of what you wrote" ) my sentence "he is forced to answer on _each_
> opposite argument in essence" has not found a good place in your sole.
All the good will in the world won't make it possible to rebut an
argument, when you can't understand the argument well enough to figure
out what it is that you need to rebut. I have to agree with James
Dennet - I can't figure out what you're saying well enough to explain
what's wrong with it.
.
> - implicitly said, that point of "misunderstands" is my bad source, not the
Yes. that is precisely the problem. Your poor command of the English
language is presenting major communications problems. That's not
intended as a criticism; it's just a regrettable fact. My Russian is
far worse than your English; I'd have far more trouble making myself
understood in a Russian language forum than you do in this one.
---
[ 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 ]
Author: jdennett@acm.org (James Dennett)
Date: Tue, 20 Mar 2007 05:52:16 GMT Raw View
Grizlyk wrote:
> James Dennett wrote:
>>>>> As I can understand, auto_ptr with move semantics was called
>>>>> "unique_ptr", but really they do the same. So do we need new
>>>>> name for auto_ptr? I think no.
>>>>> ...
>>>>> ( i already have listed 6 points of deisagreement with
>>>>> the "r-value reference" in the thread and still no one has
>>>>> denied my reasons in essence and proved that i was wrong ).
>>>>>
>>>> Your first point was:
>>>>
>>>>> 1. No auto_ptr support.
>>>>> =======================
>>>> And I've reread that point several times. I'm still failing
>>>> to see how the rvalue reference package is lacking in this area.
>>> In general. if anyone really want find answer (unknown to him), I think,
>>> he
>>> is forced to answer on _each_ opposite argument in essence. There are no
>>> other way of searching (at least i do not know other way).
>
>> By and large, I can say that I could not make any sense
>> of most of what you wrote.
>
> In comp.lang.c++ one man have told me, that it is not a good idea to discuss
> "the ways of correct discussions" mixed with topic. Maybe he was right, but
> only if his opinion is not obstacle to find topic's answers.
Sometimes it is vital to address "the ways of correct
discussion" and more constructive to also try to help
the topic along at the same time. That is what I have
attempted to do here. I hope you can understand that
this is an attempt to help you. Others will be more
able to help if they can first understand.
> I see ( looking on your reply "I can say that I could not make any sense of
> most of what you wrote" ) my sentence "he is forced to answer on _each_
> opposite argument in essence" has not found a good place in your sole.
Again, I do not quite understand what you mean, but
clearly I did answer each of your original points as
far as I could. (It's not "forced" by anything I
see, but let's ignore that.)
> I do not care do you agree with me or not, because the my sentence "he is
> forced ..." is just translation of well-known rule of formal logic.
I cannot imagine how you think that formal logic forces
*anything* on a newsgroup. (My background is in
mathematics and logic; I find it minimally applicable
to this newsgroup.)
> As
> programmer, if you will ignore any rules of formal logic in your programs,
> your programs will never do any useful, because to CPU you never can say
> "Listen, hell's CPU, I could not make any sense of most of what you doing".
And, clearly, we use logic when programming. Formal
logic applies to code in ways it does not apply to
discussions on newsgroups.
> During conversation it is the same, no any useful answer can be found with
> refusing from rules of of formal logic, the only useful example of
> conversation without the rules of formal logic is one containing no words,
> only series of useless curses to address of enemies on square meeting,
> producing loud "huraaa" from listeners.
It is not the same. Human conversations are not
conducted according to formal rules; even human
languages are not conducive to formal rules (which
is why we term them "natural languages" to distinguish
from formal languages). Our discussions are fruitless
if they are not at least consistent, but they do not
have to follow a formal framework.
> In the my text above I am speaking, that your idea "I can say that I could
> not make any sense of most of what you wrote" chiefly pointed against the
> rule "he is forced to answer on _each_ opposite argument in essence" rather
> than against me or my statements, because in order to disagree with me you
> have violated the rule twice:
> - did not list concrete error points in my text,
I could list many errors, but that would be missing
the point. The point is that there was, to me, much
of what was there had no meaning. I hope that others
are able to guess what you meant better than I can,
but the lack of substantive replies seems to suggest
that others have also been unable to work out what
you meant.
> - implicitly said, that point of "misunderstands" is my bad source, not the
> rule violation.
As I cannot even understand which rule you claim to
have been violated, I do feel that some of the problem
is the language barrier; your language skills in
English are stronger than mine in any other language,
but it is clear that English is not native.
> It is no any sense to discuss concrete problems without the rules of formal
> logic. Also, i can explain the rule in the concrete case of conversation: I
> never can guess what part of my statements has been wrong for you, and your
> attempts to avoid concrete enumerating at least some of concrete wrong
> points in my statemets often can speak that there are no wrong points there,
> but you do not agree, so you are forced to search other way of "discussion".
Not so. I made no "attempt" to avoid addressing
concrete points. Rather, I simply did not do so,
as it did not occur to me that a long list of
sentences with notes saying "this is not a
meaningful English sentence in this context"
would be helpful. The issue is not that you said
things that were wrong; the issue is that some
(maybe many) people cannot understand what it
is that you meant to say.
>> If so, it will not help to ask them what they "rejected",
>> except for the fact that your objections did not seem
>> coherent.
>
> I understand: "I do not like it, I can not say why, but probably all are
> totally non-coherent, because < here can be any unrelated to provement of
> object of discussion >".
>
>
>> Maybe I can address them somewhat:
>>
>> 1) "No auto_ptr support"
>>
>> It wasn't clear what you meant here.
>>
>
> Answer to concrete unclear sentences from original post.
I don't understand you response. Maybe I can be clearer:
It was not clear what your first point meant. The whole
section headed "No auto_ptr support" did not make sense
to me.
>> 2) "No ordered definitions
>> for "copyable" and "moveable" C++ concepts.
>>
>> It was not clear what you meant by this, or why you felt
>
> Answer to concrete unclear sentences from original post.
Again, I do not understand your sentence above. I meant
that your second point was unclear.
>> 3. "Value" is not the same as "reference"
>>
>> It was not clear what you meant here.
>
> Answer to concrete unclear sentences from original post.
(The same here.)
>> It's obviously true
>> that "value" is not the same as "reference", but that does
>> not present a problem for the proposal
>
> I have no problem, so you are wrong.
This logic is flawed; the fact that *you* have
a problem does not prove that the the fact that
the terms "value" and "reference" is a problem
for the proposal. The proposal is entirely
consistent with this fact (even though it does
give new meaning to the term reference).
>> 4. "Non-const" is not the same as "moveable".
>>
>> Again, this is well-known, and not a problem for the
>> proposal.
>
> I have no problem, so you are wrong.
That makes no sense, and does not follow. Whether
you have a problem or not, does not speak of whether
the proposal has a problem.
>> If you believe there is a problem, you will
>> need to provide convincing evidence.
>
> http://grizlyk1.narod.ru/cpp_new/#12
There's a large amount of material there. It does
not appear relevant, and much of what is there
suffers from stating as conclusions things that
are unproven or do not make sense. For example,
to be concrete, you state that "So in order to
support auto_ptr C++ must also define extra
attributes to controll access to "moveable".
Your argument does not show this to be true.
>> You write that
>> "The ownership from auto_ptr can not be transferred
>> more than one time" but this is not true; ownership
>> can be passed along an unlimited chain of auto_ptr
>> objects. Was this maybe not what you meant to write?
>
> The ownership from _concrete object of class of_ auto_ptr can not be
> transferred more than once. And context is clear speaking about it :
>
> "Also it is easy to see, that non-const can not protect us from logically
> wrong "operator move" has been applied twice to the non-const object (double
> move). We can say, that move semantic required from C++ "once" support
> rather than "non-const" support, it is really different things."
It is in the nature of "moving" a resource that once it
has been moved from a place, it is no longer there. This
is a design feature of auto_ptr (an other movable types),
not a flaw. It is not clear what you think is wrong.
A resource can be passed between auto_ptr instances many
times, but at any given time it is owned by only one of
them. In general, a movable resource need be in only
one place at a time.
>> This was also a key point in your number 5, which also
>> says (incorrectly) that auto_ptr must not be passed by
>> reference. Certainly passing auto_ptr by reference is
>> unusual, but it can be quite correct.
>
> http://grizlyk1.narod.ru/cpp_new/#11
>
> "Also it means, that there are no more than one auto_ptr with the same
> address simultaneously.
>
> Unlike to auto_ptr, we can have many POD pointers with the same address
> (that have been placed in an auto_ptr) and we can use the pointers while the
> auto_ptr exist."
That does not say anything about passing auto_ptr by
reference, does it?
>> 6. Interaction "copyable" and "moveable"
>>
>> Again, it was not clear what you meant here;
>
> Answer to concrete unclear sentences from original post.
I do not know what you mean by "answer to concrete unclear
sentences from original post".
>> could you be more explicit?
>
> http://grizlyk1.narod.ru/cpp_new/#14
>
> "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 (enumerate) all strict rules also ("functions
> expecting moveable value can use copyable value" and so on). "
This is what I am asking you to explain, rather than repeat.
>> It's possible that these problems are mine, but in general
>> I find discussions on comp.std.c++ quite easy to follow
>> (sometimes with a little work), so it's likely that if I
>> do not see what points you are trying to make then there
>> may be others who need more clarity.
>>
>> I cannot make constructive responses to most of your points
>
> It is a pity, but i can not response instead of you.
I'm afraid I can't understand what you mean by "i can not
response instead of you".
>> as they seem not to address the rvalue references subject.
>
> Becasue r-value reference is implementation of something, so i am speaking
> about the thing, the r-value reference is implementing.
I don't think that it *is* "implementation of something".
Rather, it's a new language feature which can be used to
implement a range of things. It has applications in the
areas of move semantics, of function forwarding, and no
doubt other areas too.
>> If you can express your ideas in more concrete detail, showing
>> how they actually present difficulties with the current
>> proposals in practical situations, you may well find that
>> others will support your points.
>
> Answer to concrete unclear sentences from original post, unrelated to the
> current
> proposals of r-value reference in practical situations.
Again, I'm afraid I cannot understand what you mean by
the sentence starting "Answer to concrete unclear
sentence from original post...".
> So, as funny result of the discussion - to be happy is much better to be
> unhappy. Speaking seriously, I have made the long explanation in the post in
> order to make example and to refer on the example in future, if it will be
> nessesary.
Which long explanations? I've seen many assertions, but
I would need more explanation/evidence for the claims
you make in order to determine whether they have merit.
-- 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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Mar 2007 15:07:49 GMT Raw View
David Abrahams wrote:
>
>> I see ( looking on your reply "I can say that I could not make any sense
>> of
>> most of what you wrote" ) my sentence "he is forced to answer on _each_
>> opposite argument in essence" has not found a good place in your sole.
>>
>> I do not care do you agree with me or not, because the my sentence "he is
>> forced ..." is just translation of well-known rule of formal logic.
>
> Well, not a very good translation, then. Your sentence, "he is forced
> to answer on _each_ opposite argument in essence," really is
> incomprehensible to me, as I expect it is to most native speakers of
> English.
> All the formal logic in the world won't help your argument if your
> readers can't parse it.
Exellent example of violating the considered rule. What kind of
incomprehensible? Is this kind of "hidden knowledge" for "native speakers of
English"? This looks like kind of arguments to person, not to essence, used
when agruments to essence is absent.
Let's consider the sentence "he is forced to answer on _each_ opposite
argument in essence"
-he
-is forced
-to answer
-on
"to answer on" can be a kind of "control", like "find out", "go on" etc,
changing semantics of original word "answer" and certainly i can not know
the details of english for all possible situation, but in the context "to
answer" has quite clear meaning.
-_each_ opposite argument
-in essence
All of the parts of sentence is quite correct in english grammar (rules of
comnibation of words into sentence) as well as has quite "undestandable"
semantics. Do i need to continue to answer to so deliberate wrong questions?
There is other rule of the formal logic that recommends just to do not
answer on the post like this (created with deliberate violations, is not
intended to consider original question), in order to not switch discussion
into the way of deliberate violations.
Also no reasons to answer, because even founded concrete facts of
"deliberate violations" will be quietly ignored as if nothing has happened.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Mar 2007 15:09:19 GMT Raw View
David Abrahams wrote:
>
>>> Giving auto_ptr move semantics may break existing code.
>>
>> What kind of break? The auto_ptr always was not copyable (has no copy
>> constructor).
>
> std::auto_ptr<T> has a constructor that can accept a single argument
> of std::auto_ptr<T>&. By the definition of "copy constructor" in the
> C++ the standard, that is a copy constructor.
You can find here http://grizlyk1.narod.ru/cpp_new#14 explanation why we
need other "copy constructor" definition in C++. Also you can read here
http://grizlyk1.narod.ru/cpp_new#11 why auto_ptr-like wrapper can not be
copyable.
>> The little correction _must_ be done to make auto_ptr usage
>> less dangerous (probably some errors will be found). The correction is
>> only
>> adding "moveable" to auto_ptr returned and passed by value or reference.
>> All
>> existing correct moveable usage must not require any more changes. Also
>> people can write "using old_std::auto_ptr;" and continue to collect
>> runtime
>> errors.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Mar 2007 15:10:07 GMT Raw View
kuyper@wizard.net wrote:
>
>> > By and large, I can say that I could not make any sense
>> > of most of what you wrote.
>>
>> In comp.lang.c++ one man have told me, that it is not a good idea to
>> discuss
>> "the ways of correct discussions" mixed with topic. Maybe he was right,
>> but
>> only if his opinion is not obstacle to find topic's answers.
>>
>> I see ( looking on your reply "I can say that I could not make any sense
>> of
>> most of what you wrote" ) my sentence "he is forced to answer on _each_
>> opposite argument in essence" has not found a good place in your sole.
>
> All the good will in the world won't make it possible to rebut an
> argument, when you can't understand the argument well enough to figure
> out what it is that you need to rebut. I have to agree with James
> Dennet - I can't figure out what you're saying well enough to explain
> what's wrong with it.
Well, "sole". I wanted to say "soul" (they are sounded equally), but the
sentence can be funny treated as if there is no place not only in his soul
and heart, but even in the sole of his shoes.
Probably i am often speaking as "my hed your word not anderstand". But even
if 100 men will add to the group messages, that sentence "he is forced to
answer on _each_ opposite argument in essence" has no concrete sense in
english, i will not beleive them, because if they are true, they easy could
point to concrete problems of the sentence.
Refusing to point to concrete problem is often just a sign of the fact, that
there are no any problems here, so see answer to "David Abrahams" above.
I think, we also could start referendum with a question "is the sentence 'he
is forced to answer on _each_ opposite argument in essence' has a concrete
sense in english" in order to find the truth.
--
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 ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Tue, 20 Mar 2007 11:19:03 CST Raw View
on Tue Mar 20 2007, grizlyk1-AT-yandex.ru ("Grizlyk") wrote:
> David Abrahams wrote:
>>
>> All the formal logic in the world won't help your argument if your
>> readers can't parse it.
>
> Exellent example of violating the considered rule. What kind of
> incomprehensible?
Incomprehensibility is a pretty simple concept. It doesn't
traditionally come in different varieties.
> Is this kind of "hidden knowledge" for "native speakers of
> English"?
Don't make this more complicated than it is. Your writing often does
not form correct English sentences or uses words in unfamiliar ways.
Trying to fill in missing words and alter the existing incorrect ones
to make the sentence parse correctly is error-prone for the reader and
open to a great deal of ambiguity.
> This looks like kind of arguments to person, not to essence, used
> when agruments to essence is absent.
It's hard to deal with the essence of something when you can't discern
it.
> Let's consider the sentence "he is forced to answer on _each_ opposite
> argument in essence"
>
> -he
> -is forced
Right there you've already lost me. Nobody can force anything here.
> -to answer
>
> -on "to answer on" can be a kind of "control", like "find out", "go
> on" etc, changing semantics of original word "answer" and certainly
> i can not know the details of english for all possible situation,
> but in the context "to answer" has quite clear meaning.
"To answer" is common English. "To answer on" is not, and although
I've really tried to follow you here, what you've said about control,
etc., does not help me understand what you intend to communicate by
using "on."
> -_each_ opposite argument -in essence
>
> All of the parts of sentence is quite correct in english grammar
> (rules of comnibation of words into sentence)
Yes.
> as well as has quite "undestandable" semantics.
No. I don't understand what "opposite argument" is supposed to mean.
> Do i need to continue to answer to so deliberate wrong questions?
To suggest that I'm conversing in bad faith is very poor form and
insulting (not to mention baldly calling my questions "wrong").
Anyway, to answer your question, no, you are not forced to answer any
questions, whether intended to help (as mine are) or "deliberate
wrong." You're free to ignore anyone who posts here. But surely you
knew that.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Mar 2007 16:54:00 GMT Raw View
David Abrahams wrote:
>
>> As I can understand, auto_ptr with move semantics was called
>> "unique_ptr", but really they do the same.
>
> Not exactly the same, or, as you say, we wouldn't need a new name.
> The differences in behavior would cause old, working, code to break if
> auto_ptr were simply changed to use unique_ptr semantics.
Again: I think, auto_ptr can not be good implemented without move semantics
in C++, but auto_ptr from its born was moveable, never copyable, so any old
code, already using current auto_ptr implementation correctly, will not see
any differences with new implementation, excluding old code must declare
auto_ptr as moveable
old:
auto_ptr foo(auto_ptr ptr)
{
auto_ptr tmp(ptr);
return tmp;
}
new:
moveable auto_ptr foo(const moveable auto_ptr ptr)
{
auto_ptr tmp(ptr);
return tmp;
}
That can be done often by "replace" command of any text editor. If old code
will not be able to compile after conversion like this, it means the old
code are using auto_ptr incorrectly - with UB or runtime errors.
New syntax will add no changes for algorithms, using moveable data type,
excluding explicit declarations of all moveable data as moveable.
--
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 ]
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Tue, 20 Mar 2007 12:05:45 CST Raw View
James Dennett wrote:
>
>>>> He has asked me how it can be implemented with my proposal. Try open
>>>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,
>>>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>>>> "Lvalue" means "address can be taken" and nothing more.
>>>> "Lvalue" is unrelated to "const", "copyable" or "moveable" data type.
>>>>
>>> The relationship is something that exists and has been
>>> considered in quite a lot of detail.
As I can understand, you have said, that term "relationship" must be applied
to bind "Lvalue" and "const", because of either something exist or something
can be considered in quite a lot of detail.
Then i have said, that
>> Any term, binding several objects, as relationship do, of course can be
>> considered for any combinations of any objects.
So we always can consider any term, binding several objects, and consider in
quite a lot of detail.
>> For example, we can consider
>> question about any relationships between C++ and rain in any desert.
>
> But we would not reasonably be able to consider it
> "in detail", as there is no significant relationship
> between C++ and weather in some specified geographical
> region.
It does not matter here "reasonably" or not, it is only important that we
can do consider any term, binding any several objects.
>> But the possible ability of consideration is not the same, that the
>> considered term can be applied to binding the concrete combination of the
>> concrete objects.
So I have said, that in spite of the fact, that we always can consider any
term, the existence of process of consideration is not the same, that the
considered term must be applied to binding the concrete combination of the
concrete objects.
If we have found after consideration process, that relationship is not exist
(objects unrelated), we can continue to apply the term "relationship" in the
form of "has no relationship" (unrelated).
>> For example, there are no any relationship between C++
>> and rain in any desert.
>
> Right, so that would not be a useful thing for us to
> discuss.
So you have agreed with me, that "Lvalue" can be as well related (has
relationship) as unrelated (has no relationship) to "const", "copyable" or
"moveable" data type. It does not matter either can "relationship of
"Lvalue" and "const" has been considered in quite a lot of detail" or can
not in order to be able to apply "relationship" term to bind "Lvalue" and
"const".
>> So original sentence: "there are no any relationship between "Lvalue" and
>> "const", "copyable" or "moveable" data type" is correct statement at
>> least
>> formally.
>
> How can it be correct
_formally_ it is always correct, because you have agreed with me, that
"Lvalue" can be as well related as unrelated to "const", "copyable" or
"moveable" data type.
> when others have supplied specific
> details of the concrete relationship that exists between
> rvalues and movability?
As i can guess, you does not agree with concrete _form of relationship_: i
think "unrelated", you think "related".
There are differences between "rvalues", "movability" and "moveable data
type".
Conceptually "movability" or just "moveable property" is ability of _any_
concrete object to allow to process "move" to be applyed to the object, the
property can be unrelated to the type of the object and can appear only in
one concrete _place_ of code.
Conceptually "moveable data type" is data type, that in addition to
"movability", define some other important rules of behaviour for all objects
of own types _always_.
This is important difference, because "moveable data type" related to _data
type_, but "moveable property" related to _place of code_.
The conceptual difference defines differences in behaviour for "objects of
moveable data type" and "objects only with moveable property".
The example of the difference in behaviour is RVO:
1. r-value reference FAQ
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Moving%20from%20local%20values)
[quote]
Moving from local values
A further language refinement can be made at this point. When returning a
non-cv-qualified object with automatic storage from a function, there should
be an implicit cast to rvalue:
string
operator+(const string& x, const string& y)
{
string result;
result.reserve(x.size() + y.size());
result = x;
result += y; // as if return static_cast<string&&>(result);
return result;
}The logic resulting from this implicit cast results in an automatic
hierarchy of "move semantics" from best to worst:
- If you can elide the move/copy, do so (by present language rules)
- Else if there is a move constructor, use it
- Else if there is a copy constructor, use it
- Else the program is ill formed
[/quote]
2. moveable concept as defined in http://grizlyk1.narod.ru/cpp_new
The example of "Moving from local values" will be:
a)
When returning #any# object with automatic storage from a function, there
should be an #explicit# cast to rvalue, #function must be declared
properly#:
string
operator+(const string& x, const string& y)
{
string result;
result.reserve(x.size() + y.size());
result = x;
result += y;
//here _always_ "copy constructor"
//never "move constructor"!
return result;
}
The logic resulting from this #explicit# cast results in an #explicit#
hierarchy of "copy semantics" from best to worst:
- If you can elide the move/copy, do so (by present language rules)
note, the question of "eliding" is unrelated to question of "data type"
- Else if there is a copy constructor, use it
- Else the program is ill formed
b)
If you need use moveable data type, function must be declared properly
moveable string
operator+(const string& x, const string& y)
{
string result;
result.reserve(x.size() + y.size());
result = x;
result += y;
//here either "move constructor"
//or "copy constructor"
return result;
}
The logic resulting from this #explicit# cast results in an #explicit#
hierarchy of "move semantics" from best to worst:
- If you can elide the move/copy, do so (by present language rules)
note, the question of "eliding" is unrelated to question of "data type"
- Else if there is a move constructor, use it
- Else if there is a copy constructor, use it
- Else the program is ill formed
***
The main differences is the fact, that:
- for "moveable data type", behaviour of objects defined only by class
_declaration_ and variable _declaration_ (as any ordinary C++ type _must_
do), "moveable data type" looks like "volatile data type" or "const data
type".
- but for "moveable property(r-value reference)", behaviour of objects
defined only by concrete _place_ of usage of variable of undefined type,
_never_ by declarations (as any ordinary C++ type _never_ must do).
"(r-value reference)" makes type of variable is secondary, but place is
primary condition of behaviour of variable.
***
Co-existance of "moveable property" and "moveable data type"
In theory, "moveable property" is just limited subset of "moveable data
type", but because "r-value reference" define own behaviour, orthogonal to
behaviour of ordynary C++ data type, the both of them can co-exist
simultaneoulsy.
Consider following declaration of class string, supporting all of them:
class string
{
//copyable data type
public:
string(const string&);
any_type operator= (const string&);
//r-value refinement of copyable data type
public:
string(const? string&&);
any_type operator= (const? string&&);
//moveable data type
public:
string(moveable const string&);
any_type operator= (moveable const string&)ctor;
//does not define copyable data type if unhided
//can override implicit copy ctor/assignment
public:
//compile time error
//string(string&) is hidden by
//string(const string&)
string(string&);
//compile time error
//operator= (string&) is hidden by
//operator= (const string&)
operator= (const string&)
//does not define moveable data type if unhided
//can override implicit move ctor/assignment
public:
//compile time error
//string(moveable string&) is hidden by
//string(moveable const string&)
string(moveable string&);
//compile time error
//operator= (moveable string&) is hidden by
//operator= (moveable const string&)
any_type operator= (const string&)ctor;
};
I am sure - "moveable data type" is more regular and important stuff, than
"r-value reference", so if C++ can not contain both, than "moveable data
type" must be selected.
> On the other hand, the relationship between
> rvalues and movable items is quite specific and
> meaningful
There are _no_ relationship between rvalues and "moveable data type". We can
easy imagine "conceptual moveable" as rvalue as well as lvalue.
moveable T add(const moveable T, const moveable T);
extern moveable T& src;
moveable T dst= add(src,src);
In the example above, return value of function "add" is "rvalue moveable",
but "dst" and "src" are "lvalue moveable", in spite of "src" is "reference
to moveable".
> arising from the basic notion that
> temporary objects are rvalues (even when their
> addresses can be taken)
I do not argue, that "temporary objects are rvalues".
But if address of "rvalue" can be taken, then the "rvalue" has been
implicitly casted into "lvalue", because by definition of "rvalue" - address
of "rvalue" never can be taken. For CPU's opcodes "rvalue" means data is
immediate:
enum { data=3 };
//3 -> %eax
movl $data,%eax
here "data" is "rvalue"
int data=3;
//3 -> %eax
movl data,%eax
here "data" is "lvalue", we can find its address as following:
//&data -> %eax
leal data,%eax
The fact of non-existence of address for any "rvalue" is unrelated to the
fact that "rvalue" can not be casted into "lvalue".
I can agree, that syntax "int&&" can be used to make explicit cast of
"temporary rvalue of type int" into "reference to temporary lvalue of type
int", but the question is unrelated to moveable data type. Absolutelly
unrelated to moveable as well as RVO unrelated to moveable.
I think, it can be better to call "r-value reference" as "reference to
temporary", because semantics of "reference" assuming "lvalue", because
reference always implemented as encapsulated "const pointer".
The "r-value reference" is sounded paradoxically: "address of something,
that has no address".
> and that moving from a
> temporary object is generally safe.
I do not argue, that during temporary life time "moving from a temporary
object is generally safe".
But the fact of safe moving from temporary during temporary life is
unrelated to properties of moveable data type.
This is because "conceptual moveable" is data type, that can create new
instance from itself only by moving its internal state, insted of copying
and "conceptual copyable" is data type, that can create new instance from
itself as well by moving its internal state, as by copying.
Both "conceptual moveable" and "conceptual copyable" can be as well "lvalue"
as "rvalue" or temporary.
> (Also note: "rvalue references" do not apply only to
> rvalues -- while they bind to rvalues, it is quite
> possible and useful to use an rvalue reference to
> cause a non-rvalue to be treated in the same way as
> an rvalue, such as is done by std::move.)
I will agree with "std::move" for "moveable data type" only if you will use
in your programs "std::assing" and "std::copy" for copyable. For "r-value
reference", "r-value reference" is not going to be C++ moveable data type it
does not matter.
>> And logically the original sentence is also correct, because "Lvalue"
>> means
>> "address can be taken, so memory of the expression always exist" and
>> speaking nothing related to data type.
>
> Lvalue does not mean that; with user-defined types it is
> possible to take the addresses of some rvalues,
Because you have made implicit cast rvalue to temporary lvalue. And the fact
that class is not POD type do not prevent compiler to make compile time copy
of the class as rvalue (at least it can be done in future).
> and taking
> the addresses of certain lvalues can be prevented.
Can you write example of the prevention?
>> So we can easy imaging at least
>> conceptual "moveable" object, address of which can be taken as well as
>> can
>> not, so there is "Lvalue moveable" as well as "Rvalue moveable" in C++.
>
> That's true, and the rvalue reference proposal allows for
> expressing movement from lvalues via std::move.
There are no relationship between "conceptual moveable" and "Rvalue". To be
moveable is defined by the class declaration, never by "std::move from
lvalue".
> Do you
> think there is an inability to express this with the
> current proposals? Are you familiar with std::move?
I will agree with "std::move" for "moveable data type" only if you will use
in your programs "std::assing" and "std::copy" for copyable. For "r-value
reference", "r-value reference" is not going to be C++ moveable data type it
does not matter.
>> Rvalue is not the term that can be used to declare any data type,
>> including
>> moveable data type. The fact, that some rvalue expressions looks like
>> "moveable" is just accident.
>
> It's not clear to me what you mean here. It's certainly
> true that there is a fundamental reason why moving from
> temporaries is a reasonable thing; that is not just an
> accident.
What exactly not clear? By accident means rvalue _looks_ like moveable by
accident. It is not core property of rvalue. That is just an accident,
because non-accident property of any data type can be defined _only by
declaration_, never by accident.
I think, the "r-value reference" is just not a data type, it is special set
of rules to work with copyable data type in special places of code,
unrelated to data type declaration.
The "r-value reference" never can replace ordinary moveable data type (
"r-value reference" is just limited subset of correct moveable data type and
"r-value reference" has special rules to interacts with copyable, the rules
does not dedined by class decalration ) because with the help of "r-value
reference" user never will be able to express simplest kind of algorithms
with moveable data type.
It is especially touching, when one can see, that C++ easy can support
complete moveable data type.
--
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 ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Tue, 20 Mar 2007 12:56:47 CST Raw View
on Tue Mar 20 2007, grizlyk1-AT-yandex.ru ("Grizlyk") wrote:
> David Abrahams wrote:
>>
>>> As I can understand, auto_ptr with move semantics was called
>>> "unique_ptr", but really they do the same.
>>
>> Not exactly the same, or, as you say, we wouldn't need a new name.
>> The differences in behavior would cause old, working, code to break if
>> auto_ptr were simply changed to use unique_ptr semantics.
>
> Again: I think, auto_ptr can not be good implemented without move semantics
> in C++, but auto_ptr from its born was moveable, never copyable, so any old
> code, already using current auto_ptr implementation correctly, will not see
> any differences with new implementation, excluding old code must declare
> auto_ptr as moveable
>
> old:
>
> auto_ptr foo(auto_ptr ptr)
> {
> auto_ptr tmp(ptr);
> return tmp;
> }
>
> new:
>
> moveable auto_ptr foo(const moveable auto_ptr ptr)
> {
> auto_ptr tmp(ptr);
> return tmp;
> }
>
> That can be done often by "replace" command of any text editor. If old code
> will not be able to compile after conversion like this, it means the old
> code are using auto_ptr incorrectly - with UB or runtime errors.
In other words, "Again:" the differences in behavior would cause old,
working, code to break if auto_ptr were simply changed to use
unique_ptr semantics. It is taken for granted by the proposers of
unique_ptr -- who have a lot of experience with what sorts of changes
will be accepted or rejected by the C++ committee -- that such
breakage would be unacceptable even if it "can be fixed by the replace
command of any text editor."
You may disagree with us about what the commitee will accept. In that
case feel free to submit your own proposal and argue for it at the
next committee meeting.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Mar 2007 19:40:59 GMT Raw View
on Tue Mar 20 2007, "Grizlyk" <grizlyk1-AT-yandex.ru> wrote:
> David Abrahams wrote:
>>
>>> What kind of break? The auto_ptr always was not copyable (has no copy
>>> constructor).
>>
>> std::auto_ptr<T> has a constructor that can accept a single argument
>> of std::auto_ptr<T>&. By the definition of "copy constructor" in the
>> C++ the standard, that is a copy constructor.
>
> You can find here http://grizlyk1.narod.ru/cpp_new#14 explanation why we
> need other "copy constructor" definition in C++. Also you can read here
> http://grizlyk1.narod.ru/cpp_new#11 why auto_ptr-like wrapper can not be
> copyable.
Regardless of your desire for a new definition of "copy constructor,"
that term has an existing, accepted definition. Using the same term
with a different meaning here can only lead to confusion.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Mar 2007 19:43:10 GMT Raw View
on Tue Mar 20 2007, grizlyk1-AT-yandex.ru ("Grizlyk") wrote:
>>> I see ( looking on your reply "I can say that I could not make any
>>> sense of most of what you wrote" ) my sentence "he is forced to
>>> answer on _each_ opposite argument in essence" has not found a
>>> good place in your sole.
>>
> Refusing to point to concrete problem is often just a sign of the fact, that
> there are no any problems here, so see answer to "David Abrahams" above.
It's not a refusal. The problem is that I can't read more than a few
words of that statement without having comprehensibility problems, so
it looks like nearly every part has a problem. At that point it
becomes in my mind a mere pile of tiny phrases, and pointing out
problems seems futile. However, now that I understand the kind of
specificity you're after, let's break it down as you have elsewhere:
In general, if anyone really want find answer (unknown to him), I
think, he - OK
is forced to - marginally OK; nobody can be forced to do anything in this
NG. Maybe you mean something like "must?"
answer - OK in isolation, but later the object of "answer" is
"argument." What does it mean to "answer (on) an
argument?" Do you mean "rebut?"
on - not OK; nobody says "to answer on," so we don't know
what you mean by "on" here.
_each_ - OK in isolation
opposite argument - not OK. What is an "opposite argument?" Do you
mean "opposing argument?"
in essence - not OK. What does it mean to do anything "in
essence?" In English when we say "in essence," it
means something like "fundamentally." Maybe you mean
"in its essence?"
One can guess at the answers to some of these questions, but when one
has to make a guess every few words in a sentence, it leaves the
reader highly uncertain that the sentence has been understood.
Also, if you take all my guesses together, it doesn't seem like a very
likely assertion. There are many ways to learn. I'm sure you've
found answers unknown to you without "rebutting opposing arguments in
their essence." So I tend to assume what you were _trying_ to say
makes more sense than that, and that my guesses were wrong.
Finally, if it takes this much writing to point out the
comprehensibility issues in a single sentence (one that is arguably
more understandable than many in your earlier posts), I hope you can
imagine that few people would be willing to make the effort to do the
same thing for all the difficult sentences in a long posting.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Tue, 20 Mar 2007 14:45:19 CST Raw View
"Grizlyk" wrote:
> David Abrahams wrote:
.
> > All the formal logic in the world won't help your argument if your
> > readers can't parse it.
>
> Exellent example of violating the considered rule. What kind of
> incomprehensible? Is this kind of "hidden knowledge" for "native speakers of
> English"?
That knowledge is widely published in textbooks explaining the correct
usage of English. Native speakers generally don't need those textbooks
as much as non-native speakers do, but there's nothing hidden or
specific to native speakers about that knowledge.
> ... This looks like kind of arguments to person, not to essence, used
> when agruments to essence is absent.
You need to distinguish between yourself and your writings. You might
be a wonderful person, with some very important insights into C++.
We're not criticizing you. We are criticizing the quality of your
written English, which is simply not adequate for this discussion. If
we were to suggest that the way you write reflects the way you
actually think, that would be a personal insult; but I don't believe
that - I think your written English is simply not good enough to
express these complicated thoughts clearly in it.
When your English is so poor that we can't figure out the essence of
your arguments, it's not really possible to put together a rebuttal
that addresses that essence.
> Let's consider the sentence "he is forced to answer on _each_ opposite
> argument in essence"
>
> -he
> -is forced
> -to answer
>
> -on
> "to answer on" can be a kind of "control", like "find out", "go on" etc,
No, it cannot. While I know that this construct is incorrect, I don't
remember the correct grammatical jargon for explaining what's wrong
with it. However, I am quite certain that it's an incorrect English
construction. I suspect that what you should do is remove the "on",
but you seem quite certain that it modifies "answer" in a way that
conveys some distinction which is of importance to you, so that might
not be the right fix.
> changing semantics of original word "answer" and certainly i can not know
> the details of english for all possible situation, but in the context "to
> answer" has quite clear meaning.
>
> -_each_ opposite argument
You probably mean "opposing" rather than "opposite".
> -in essence
This doesn't belong in this location in the sentence. Again, I don't
remember how to explain the rule, but this should be removed.
Inserting "the essence of" before the word "each" would probably
convey your intended meaning.
> All of the parts of sentence is quite correct in english grammar (rules of
No, they are not. Applying all of my suggestions, I get:
He is forced to answer the essence of each opposing argument.
Unfortunately, this was one of your clearer sentences. Most of them
are much harder to figure out.
> comnibation of words into sentence) as well as has quite "undestandable"
> semantics.
I'm sorry, but even with the grammar mistakes corrected, the semantics
of your sentence do not make any sense. How is someone supposed to
answer the essence of an argument, when he can't figure out how to
parse the words that make up the argument?
> Do i need to continue to answer to so deliberate wrong questions?
These questions are not "wrong", nor are they deliberately so. You
don't need to answer them if you don't want to - you don't need to do
anything. However, you should continue to answer them if you have any
desire to actually be understood.
---
[ 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 ]
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 20 Mar 2007 14:55:33 CST Raw View
In article <etoqpf$vlp$1@aioe.org>, "Grizlyk" <grizlyk1@yandex.ru>
wrote:
> The "r-value reference" never can replace ordinary moveable data type (
> "r-value reference" is just limited subset of correct moveable data type and
> "r-value reference" has special rules to interacts with copyable, the rules
> does not dedined by class decalration ) because with the help of "r-value
> reference" user never will be able to express simplest kind of algorithms
> with moveable data type.
I would be interested in your implementation of std::remove (from
<algorithm>). As an example, it might go a long way towards explaining
your proposal.
Or if not std::move, a generic insertion_sort algorithm along the lines
of:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html#insert
ion_sort
I'm looking for something that will work when the value_type has only a
copy constructor/assignment (e.g. complex<double>), when the value_type
has both copy and move constructors/assignments, e.g. string (and move
is preferred for performance reasons), and when the value_type has
disabled (private) copy semantics but public move members (like the
proposed unique_ptr).
It is not clear to me if this will require 1, 2 or 3 generic functions,
exactly what (if anything) has to be declared movable and/or const, and
if any other keywords will be needed to disable compile-time double move
detection.
-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 ]
Author: James Dennett <jdennett@acm.org>
Date: Wed, 21 Mar 2007 00:17:50 CST Raw View
Grizlyk wrote:
> James Dennett wrote:
>>>>> He has asked me how it can be implemented with my proposal. Try open
>>>>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,
>>>>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>>>>> "Lvalue" means "address can be taken" and nothing more.
>>>>> "Lvalue" is unrelated to "const", "copyable" or "moveable" data type.
>>>>>
>>>> The relationship is something that exists and has been
>>>> considered in quite a lot of detail.
>
> As I can understand, you have said, that term "relationship" must be applied
> to bind "Lvalue" and "const", because of either something exist or something
> can be considered in quite a lot of detail.
You misstate me. The fact that the relationship has
been discussed in much detail, and that the details
are significant, specific and reasonable, is very,
very strong evidence for its existence. If you wish
to claim, in spite of such evidence, that there is no
connection, you need to refute this somehow.
> Then i have said, that
>
>>> Any term, binding several objects, as relationship do, of course can be
>>> considered for any combinations of any objects.
>
> So we always can consider any term, binding several objects, and consider in
> quite a lot of detail.
That is not true; if there is no significant relationship,
there is no significant detail to consider.
>>> For example, we can consider
>>> question about any relationships between C++ and rain in any desert.
>> But we would not reasonably be able to consider it
>> "in detail", as there is no significant relationship
>> between C++ and weather in some specified geographical
>> region.
>
> It does not matter here "reasonably" or not, it is only important that we
> can do consider any term, binding any several objects.
Reasonableness is very important. If you do not consider
reasonableness as a crucial factor in discussions, it is
unlikely that your discussions will be fruitful.
>>> But the possible ability of consideration is not the same, that the
>>> considered term can be applied to binding the concrete combination of the
>>> concrete objects.
>
> So I have said, that in spite of the fact, that we always can consider any
> term, the existence of process of consideration is not the same, that the
> considered term must be applied to binding the concrete combination of the
> concrete objects.
>
> If we have found after consideration process, that relationship is not exist
> (objects unrelated), we can continue to apply the term "relationship" in the
> form of "has no relationship" (unrelated).
That would be most unhelpful. It is not consistent to say
that there is a relationship and that the items have no
relationship. This is a self-contradictory use of
terminology, which is why precision in terminology is
vital in these discussions.
>>> For example, there are no any relationship between C++
>>> and rain in any desert.
>> Right, so that would not be a useful thing for us to
>> discuss.
>
> So you have agreed with me, that "Lvalue" can be as well related (has
> relationship) as unrelated (has no relationship) to "const", "copyable" or
> "moveable" data type.
That is untrue. I do not agree with that, and I have
never stated anything to suggest that I do.
> It does not matter either can "relationship of
> "Lvalue" and "const" has been considered in quite a lot of detail" or can
> not in order to be able to apply "relationship" term to bind "Lvalue" and
> "const".
This "argument" does not seem to be based on logic.
>>> So original sentence: "there are no any relationship between "Lvalue" and
>>> "const", "copyable" or "moveable" data type" is correct statement at
>>> least
>>> formally.
>> How can it be correct
>
> _formally_ it is always correct, because you have agreed with me, that
> "Lvalue" can be as well related as unrelated to "const", "copyable" or
> "moveable" data type.
I have not agreed with you, and it is not correct.
Again, a false premise (that I have agreed with you)
leads to a false conclusion (that your statement
was factually correct). Reasoning from valid
premises, using logic, will be much more likely
to avoid reaching false conclusions.
>> when others have supplied specific
>> details of the concrete relationship that exists between
>> rvalues and movability?
>
> As i can guess, you does not agree with concrete _form of relationship_: i
> think "unrelated", you think "related".
If there is a relationship, they are related. This is what
the words mean in English.
> There are differences between "rvalues", "movability" and "moveable data
> type".
Yes, obviously.
> Conceptually "movability" or just "moveable property" is ability of _any_
> concrete object to allow to process "move" to be applyed to the object, the
> property can be unrelated to the type of the object and can appear only in
> one concrete _place_ of code.
With our normal definitions of the terms, this is not
true. Maybe you are using other definitions?
> Conceptually "moveable data type" is data type, that in addition to
> "movability", define some other important rules of behaviour for all objects
> of own types _always_.
>
> This is important difference, because "moveable data type" related to _data
> type_, but "moveable property" related to _place of code_.
>
> The conceptual difference defines differences in behaviour for "objects of
> moveable data type" and "objects only with moveable property".
>
> The example of the difference in behaviour is RVO:
>
> 1. r-value reference FAQ
> (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm#Moving%20from%20local%20values)
>
> [quote]
> Moving from local values
>
> A further language refinement can be made at this point. When returning a
> non-cv-qualified object with automatic storage from a function, there should
> be an implicit cast to rvalue:
> string
> operator+(const string& x, const string& y)
> {
> string result;
> result.reserve(x.size() + y.size());
> result = x;
> result += y; // as if return static_cast<string&&>(result);
> return result;
> }The logic resulting from this implicit cast results in an automatic
> hierarchy of "move semantics" from best to worst:
>
> - If you can elide the move/copy, do so (by present language rules)
> - Else if there is a move constructor, use it
> - Else if there is a copy constructor, use it
> - Else the program is ill formed
>
> [/quote]
What do you aim to illustrate with this quote?
> 2. moveable concept as defined in http://grizlyk1.narod.ru/cpp_new
>
> The example of "Moving from local values" will be:
>
> a)
> When returning #any# object with automatic storage from a function, there
> should be an #explicit# cast to rvalue, #function must be declared
> properly#:
>
> string
> operator+(const string& x, const string& y)
> {
> string result;
> result.reserve(x.size() + y.size());
> result = x;
> result += y;
>
> //here _always_ "copy constructor"
> //never "move constructor"!
> return result;
> }
Even C++98 avoided the need to copy in that case. Are you
proposing a move backwards from RVO?
> The logic resulting from this #explicit# cast results in an #explicit#
> hierarchy of "copy semantics" from best to worst:
>
> - If you can elide the move/copy, do so (by present language rules)
>
> note, the question of "eliding" is unrelated to question of "data type"
>
> - Else if there is a copy constructor, use it
> - Else the program is ill formed
>
> b)
> If you need use moveable data type, function must be declared properly
>
> moveable string
> operator+(const string& x, const string& y)
> {
> string result;
> result.reserve(x.size() + y.size());
> result = x;
> result += y;
>
> //here either "move constructor"
> //or "copy constructor"
> return result;
> }
What is the motivation for this? What benefit does it
have over the current wording for C++ with rvalue
references?
I'm afraid I lack the time to respond to the rest of your
post. There's a lot of material, and each small part takes
a long time to try to understand, and even then I am largely
unsuccessful in working out what you could mean. Maybe
others will do better, or maybe you can work out a way to
translate your ideas more conventionally?
-- 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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Fri, 16 Mar 2007 14:21:42 GMT Raw View
Howard Hinnant wrote:
>
>> As I can understand, auto_ptr with move semantics was called
>> "unique_ptr",
>> but really they do the same. So do we need new name for auto_ptr? I think
>> no.
>> ...
>> ( i already have listed 6 points of deisagreement with
>> the "r-value reference" in the thread and still no one has denied my
>> reasons
>> in essence and proved that i was wrong ).
>
> Your first point was:
>
>> 1. No auto_ptr support.
>> =======================
>
> And I've reread that point several times. I'm still failing to see how
> the rvalue reference package is lacking in this area.
In general. if anyone really want find answer (unknown to him), I think, he
is forced to answer on _each_ opposite argument in essence. There are no
other way of searching (at least i do not know other way).
>From practical life i know, that often refusing to do it (answering)
speaking only about absence of desire to obtain any answer disagreeing with
predefined wanted result, because "i do not need", "i do not want" and other
the same reasons.
In the concrete accident of auto_ptr implemented with "rvalue reference" i
can only repeat my previuos 6 arguments, because i do not know what part of
the arguments (for each concrete problem) has been rejected by you.
Also you can read my message in the thread from 15.03.07 with words: "One
can see the steps of "moveable concept" appearence". The message "in short
form" describes problems of auto_ptr implementation and problems of moveable
support in the language as C++. More detailed explanaitions can be found on
my page http://grizlyk1.narod.ru/cpp_new articles #11-#15.
> I recently wrote to another forum what I perceive as the major problem
> with our current auto_ptr and why it needs to be replaced. I am
> repeating that text here to answer why I believe auto_ptr needs a new
> name:
>
> My problem with auto_ptr stems from its use as a value_type in
> sequence-modifying (user-written) generic code. The fear stems from
> early implementations of std::sort, but I think the same type of problem
> could occur in other sequence modifying algorithms:
>
> template<class RandomAccessIterator, class Compare>
> void
> sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
> {
> ...
> // choose a partition element with RandomAccessIterator i
> // and store it in a local
> value_type median = *i;
What is problem? There is no any "move" in the expression. Also there is
pointer here.
> // Now partition sequence with respect to median
> ...
> // median never assigned back into the range.
> // Why would I? *i is still there!
> }
>
> Now when you call this with say:
>
> std::auto_ptr<int> my_array[10];
> .
> std::sort(my_array, my_array+10, indirect_less<int>());
>
> then you are likely to get a run time error (i.e. a crash). The cause
> of the problem is that when the generic code author writes:
>
> value_type median = *i;
>
> he's thinking *copy*.
> *i should remain unchanged in his mind.
And he is absolutely right, because moveable can not be compiled here,
because copy ctor is private in this context for any moveable.
Can we write like this?
moveable value_type median = *i;
It is depended, for example, from RandomAccessIterator declaration.
It is really very hard to anybody to learn more about "moveable" and
"compile time attributes" considering the complex examples with "references
to moveable" and "interactions of copyable and moveable". See my page
http://grizlyk1.narod.ru/cpp_new articles #11-#15 to learn about all of
these in "step by step" mode.
Take in account, the syntax on the page is still "draft of first proposal",
so in general it is correct and will remain unchanged, but some little (i
hope little) details can be undefined.
After reading the page you can easy write the following example yourself.
RandomAccessIterator is a kind of pointer to walk over container, if we will
make the pointer as wrapper, we can increase compile time control of the
data hidden by the interator (increase only for each step).
The possible declarations of moveable:
moveable T& RandomAccessIterator::operator*();
T::T(const moveable T&);
But this is incompatible with "T(*i)", because skipped attributes (skipped
because the are chiefly will be the same for all classes) of moveable
references is incompatible.
With explicitly declared default attributes declarations the previous
declarations will be:
moveable T&:(...;same) RandomAccessIterator::operator*();
T::T(const moveable T&:(ctor;dtor));
it is means "T(*i)" can not be compiled:
+ *i returns undefined attribute "..." //ok
+ "..." compared with "ctor" befor "move ctor" called //ok
and "same" is assigned to "ctor" //ok
- "same" compared with "dtor" after "move ctor" called //error
= can not compile
Now we can write to make "move" like this:
moveable T T::operator< ()const dtor;
moveable value_type median = <*i;
> But when
> the type of *i is auto_ptr, then sort's author's assumptions are
> incorrect.
If auto_ptr will be decared as "only moveable", the code can not be
compiled. As i can see, the example does not deny usage of correct declared
auto_ptr.
Do you want to say, that there are differences between copyable and moveable
in algorithms?
It is evidently, that moveable data type is more limited than copyable one.
You must use _special_ algorithms to support moveable.
For already existing code you probably will be forced to re-design _core_ of
your algorithms. It is not enough only to redeclare all parameters as
"moveable".
It is the same as if you will add to C++ "const" keyword and for old code
without the "const" support will try just redeclare all data as "const". It
will not work and good compiler must detect the kind of errors appered
together with new "moveable" or "const" keyword.
This is example of simplest differences of copyable and moveable core of
algorithms:
template<class T>
void foo(const T t)
{
...
const T tmp1(t);
...
const T tmp2(t);
};
template<class T>
void foo(const moveable T t)
{
...
const moveable T tmp1(t);
...
const moveable T tmp2(tmp1);
};
>
> So who's wrong? The author of the generic code for believing that:
>
> value_type median = *i;
>
> is a copy? Or is the author of type who allows a mutating copy from an
> lvalue wrong?
I think the fact that (*i) is lvalue (has allocated memory and its address
can be taken) out of the question scope.
Also we no need any "mutating copy" definitions, we need only "moveable" and
"copyable" definition, so here wrong are:
- user, who pass moveable into template developed only for copyable
- C++, in which developer can not clear express what he want to do
>
> My belief is the latter. So "fixing auto_ptr" would involve changing it
> such that:
>
> value_type median = *i;
>
> causes a compile time error (to prevent the run time error in the
> generic code). In non-generic code, this means that:
>
> auto_ptr<A> p1;
> auto_ptr<A> p2 = p1; // must not compile
Exactly, because for moveable data type "copy ctor" is private in this
context. You must write like this:
auto_ptr<A> p1;
moveable auto_ptr<A> p2 = p1; // compile ok
*p2; // compile ok
*p1; // compile error
Here "move ctor" will be used.
> But I do not believe we can apply this fix to auto_ptr because of
> backwards compatibility concerns.
Any, who is using auto_ptr in its algorithms correctly will not see any
differences excluding they must declare "moveable". Also they can continue
to use "old_std::auto_ptr".
> Instead, people who are willing to
> take the backwards compatibility hit will vote by changing their usage
> to unique_ptr (which is essentially just an auto_ptr with the mutating
> copy disabled -- from lvalues only).
The unique_ptr is alias of "correct_auto_ptr". Do we need
"incorrect_auto_ptr" as standard "auto_ptr" tool for backwards compatibility
reasons? I am not sure.
> So, suggestions for "fixing auto_ptr" should really be clear about
> exactly what is being fixed, and what that cost is in terms of backwards
> compatibility is.
> Imho, no matter what we do to fix it, if it moves
> from lvalues with copy syntax, then the very biggest problem with it
> hasn't been fixed.
No, auto_ptr uses "copy syntax" only because C++ does not support "moveable"
and "move syntax". In current version of C++ it is user responsibility to
control moveable data type.
The new correct redeclaration of "std::auto_ptr" for 'C++ with "moveable"
support' will not change core of user code (he will need to add only
"moveable" keyword to declarations), if the user code already correcltly
treats "auto_ptr" as moveable data type.
> Any other problems auto_ptr may have are trivial
> annoyances in comparison.
They are not exist maybe, other problems in addition to problem of C++,
which does not support "moveable".
***
It is important to note, that speaking about "auto_ptr" in my original post
i am speaking not only about "std::auto_ptr". Anyway, it does no matter will
std::auto_ptr be correct or not (any can just ignore any incorrect
declarations from std namespace), because i am speaking mostly about
user-defined auto_ptr-like wrappers.
I want to say, that C++ must have stuffs to allow to user to write own
wrappers or freely do other work with moveable data type and i want to say,
that the concrete current form of "r-value reference proposal" as
implementation of moveable data type can not be the stuff of C++.
The opinion is explained with details in other 5 points of disagreement and
on my page (http://grizlyk1.narod.ru/cpp_new #11-#15).
--
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 ]
Author: "=?iso-8859-1?q?Pedro_Lamar=E3o?=" <pedro.lamarao@gmail.com>
Date: Fri, 16 Mar 2007 12:58:06 CST Raw View
On 15 mar, 14:50, grizl...@yandex.ru ("Grizlyk") wrote:
> Pedro Lamar o wrote:
> > lt& doesn't mean "reference to copyable", it means "reference to
> > lvalue".
> As i can understand, temporary can not be assigned to "non-const reference"
> only due to the reference can be passed out of the temporary scope and
> writing into non-existing stack of the terminated function for some people
> looks like more dangerous when reading from the non-existing memory or
> calling functions with random entry point, that can be done with the
> temporary assigned to "const reference".
This may have been the rationale for for the current rules for
reference binding.
The rationale being accepted the rules were set.
The current working paper has new syntax for references.
References declared with this new syntax have binding new rules.
These new rules, governing this new syntax, do allow for temporaries
to be bound to references.
It has been found that these new rules satisfy the desire for
expressing Moveable.
You seem to disagree and we seem to not understand why.
> > and b is of type bar, and bar is not Copyable.
>
> In spite the "bar" is undeclared, i trust you.
My mistake, a copy and paste error.
I meant for "bar" to be "resource".
I'll try again.
You are telling me that "T const&" requires T to be Copyable.
If this is true, how can the following code be valid?
class resource {
public:
resource ();
private:
resource (resource const&);
resource& operator= (resource const&);
};
template <typename T>
void
foo (T const& t) { }
void
f () {
resource r1;
foo(r1);
}
--
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 ]
Author: jdennett@acm.org (James Dennett)
Date: Sat, 17 Mar 2007 16:56:46 GMT Raw View
Grizlyk wrote:
> Howard Hinnant wrote:
>>> As I can understand, auto_ptr with move semantics was called
>>> "unique_ptr",
>>> but really they do the same. So do we need new name for auto_ptr? I think
>>> no.
>>> ...
>>> ( i already have listed 6 points of deisagreement with
>>> the "r-value reference" in the thread and still no one has denied my
>>> reasons
>>> in essence and proved that i was wrong ).
>> Your first point was:
>>
>>> 1. No auto_ptr support.
>>> =======================
>> And I've reread that point several times. I'm still failing to see how
>> the rvalue reference package is lacking in this area.
>
> In general. if anyone really want find answer (unknown to him), I think, he
> is forced to answer on _each_ opposite argument in essence. There are no
> other way of searching (at least i do not know other way).
>
>>From practical life i know, that often refusing to do it (answering)
> speaking only about absence of desire to obtain any answer disagreeing with
> predefined wanted result, because "i do not need", "i do not want" and other
> the same reasons.
>
> In the concrete accident of auto_ptr implemented with "rvalue reference" i
> can only repeat my previuos 6 arguments, because i do not know what part of
> the arguments (for each concrete problem) has been rejected by you.
By and large, I can say that I could not make any sense
of most of what you wrote. It's quite possible that
others could not understand what you meant either. If
so, it will not help to ask them what they "rejected",
except for the fact that your objections did not seem
coherent.
Maybe I can address them somewhat:
1) "No auto_ptr support"
It wasn't clear what you meant here. rvalues as proposed
*do* allow for a better solution to the problem that was
addressed by auto_ptr.
2) "No ordered definitions
for "copyable" and "moveable" C++ concepts.
It was not clear what you meant by this, or why you felt
that it was a problem with the rvalue reference proposal.
3. "Value" is not the same as "reference"
It was not clear what you meant here. It's obviously true
that "value" is not the same as "reference", but that does
not present a problem for the proposal, which does not
make any assumption that values and references are the
same.
4. "Non-const" is not the same as "moveable".
Again, this is well-known, and not a problem for the
proposal. If you believe there is a problem, you will
need to provide convincing evidence. You write that
"The ownership from auto_ptr can not be transferred
more than one time" but this is not true; ownership
can be passed along an unlimited chain of auto_ptr
objects. Was this maybe not what you meant to write?
This was also a key point in your number 5, which also
says (incorrectly) that auto_ptr must not be passed by
reference. Certainly passing auto_ptr by reference is
unusual, but it can be quite correct.
6. Interaction "copyable" and "moveable"
Again, it was not clear what you meant here; could you
be more explicit?
It's possible that these problems are mine, but in general
I find discussions on comp.std.c++ quite easy to follow
(sometimes with a little work), so it's likely that if I
do not see what points you are trying to make then there
may be others who need more clarity. I cannot make
constructive responses to most of your points as they
seem not to address the rvalue references subject. If
you can express your ideas in more concrete detail, showing
how they actually present difficulties with the current
proposals in practical situations, you may well find that
others will support your points.
-- 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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Sun, 18 Mar 2007 15:29:53 GMT Raw View
James Dennett wrote:
>>
>> He has asked me how it can be implemented with my proposal. Try open
>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,
>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>> Lvalue
>> means "address can be taken" and nothing more. "Lvalue" is unrelated to
>> "const", "copyable" or "moveable" data type.
>
> The relationship is something that exists and has been
> considered in quite a lot of detail.
Any term, binding several objects, as relationship do, of course can be
considered for any combinations of any objects. For example, we can consider
question about any relationships between C++ and rain in any desert.
But the possible ability of consideration is not the same, that the
considered term can be applied to binding the concrete combination of the
concrete objects. For example, there are no any relashionship between C++
and rain in any desert.
So original sentence: "there are no any relashionship between "Lvalue" and
"const", "copyable" or "moveable" data type" is correct statement at least
formally.
And logically the original sentence is also correct, because "Lvalue" means
"address can be taken, so memory of the expression always exist" and
speaking nothing related to data type. So we can easy imaging at least
conceptual "moveable" object, address of which can be taken as well as can
not, so there is "Lvalue moveable" as well as "Rvalue moveable" in C++.
Rvalue is not the term that can be used to declare any data type, including
moveable data type. The fact, that some rvalue expressions looks like
"moveable" is just accident.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Sun, 18 Mar 2007 15:31:13 GMT Raw View
Pedro Lamarao wrote:
>
>> > lt& doesn't mean "reference to copyable", it means "reference to
>> > lvalue".
>
>> As i can understand, temporary can not be assigned to "non-const
>> reference"
>> only due to the reference can be passed out of the temporary scope and
>> writing into non-existing stack of the terminated function for some
>> people
>> looks like more dangerous when reading from the non-existing memory or
>> calling functions with random entry point, that can be done with the
>> temporary assigned to "const reference".
>
> This may have been the rationale for for the current rules for
> reference binding.
> The rationale being accepted the rules were set.
>
> The current working paper has new syntax for references.
> References declared with this new syntax have binding new rules.
I have said, that differences between "reference to lvalue of type" and
"reference to rvalue of type" has been introduced not due to existence of
"rvalue data type" or due to there are any real important noticable
differences between "reference to lvalue of type" and "reference to rvalue
of type", but only due to possible writing into wrong memory via "reference
to temporary".
I am sure and have listed some concrete arguments, that term "reference" and
its semantics is alredy well defined in C++, does not need to be replaced by
any other stuffs, at least in order to support moveable semantics.
> These new rules, governing this new syntax, do allow for temporaries
> to be bound to references.
This is really different questions between "temporaries to be bound to
references" and "existence of moveable data type".
> It has been found that these new rules satisfy the desire for
> expressing Moveable.
It is very shallow explanation ( somewhere somebody has found something ),
especially when concrete opposite agruments have been listed by me, that
these "new rules" _can not_ satisfy the desire for expressing Moveable.
> You seem to disagree and we seem to not understand why.
This is really different questions between "temporaries to be bound to
references" and "existence of moveable data type".
I am sure and have listed some concrete arguments, that "term reference" and
"semantics of reference" is alredy well defined in C++, does not need to be
replaced by any other stuffs, _at least_ in order to only support moveable
semantics.
If we want to completely support "moveable data type and semantics" we must
"change direction" of "r-value reference" proposal.
> You are telling me that "T const&" requires T to be Copyable.
> If this is true, how can the following code be valid?
>
> class resource {
> public:
> resource ();
> private:
> resource (resource const&);
> resource& operator= (resource const&);
> };
Here the class "resource" has been declared as non-copyable, but probably as
moveable, only if compiler can do auto generation of "move constructor:
resource (moveable resource const&)" (as for "copy constructor" do), else
the class "resource" as well non-copyable as non-moveable.
> template <typename T>
> void
> foo (T const& t) { }
Here the function "foo<>" has no body and is declaring "t" is to be
copyable, but never used the fact.
>
> void
> f () {
> resource r1;
> foo(r1);
assuming
foo<resource>(r1);
Here "probably-moveable resource" has been passed as "reference to const
copyable", and it is correct, due to "foo<>" does not used the requirement
of "t" is to be copyable.
> }
***
I think we need to allow explicit declarations of parameter of template or
function is to be exactly copyable or moveable?
template <test typename T>void foo (T const& t);
template <test moveable typename T>void foo (T const& t);
class T;
void foo (test T const& t);
void boo (test moveable T const& t);
Here compiler will test that concrete concrete "T" has public copy/move
ctor. It makes declarations more clear and more independent from its
implementation:
template <test typename T>
void
foo (T const& t);
it is the same as
template <typename T>
void
foo (test T const& t);
Here your example
foo<resource>(r1);
will not be compileable, due to "resource" is non-copyable.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Mon, 19 Mar 2007 15:22:44 GMT Raw View
James Dennett wrote:
>
>>> struct A {...};
>>> A save_state;
>>>
>>> void throw_my_exception {throw my_exception();}
>>>
>>> void f()
>>> {
>>> A a1;
>>> // ...
>>> if (there_is_an_error)
>>> {
>>> save_state = std::move(a1);
>>> throw_my_exception();
>>> }
>>> // ...
>>> A a2 = std::move(a1); // compile-time error?
>>> // ...
>>> }
>>
>> I was suspecting it. This is a case when you rely on unknown
>> implementation
>> of "throw_my_exception()", that the function will never return. You
>> probably
>> think compiler must take the case into account for moveable (in spite it
>> will not work even with copyable) and you must not explicit tell to
>> compiler
>> about the fact.
>
> This is not a case of relying on an unknown implementation;
> the code is very explicit, it detected an error and it
> called a function to throw an exception.
This is absolutely implicit code and case of relying on an unknown
implementation of "throw_my_exception". Here "throw" probably will be called
indirectly by implementation "throw_my_exception", but C++ does not garantee
the fact, so usage of the code is UB - the result depended not from the
code, but from unknown implementation of "throw_my_exception".
> Clear and correct for a human;
A human can guess what is assumed, but the code is possible place of hidden
errors, mostly because of C++, that does not allow declare functions with
throw as return.
You can avoid the problem modifing the code like this
if (there_is_an_error)
{
save_state = std::move(a1);
throw_my_exception();
//the return will never used, but compiler will know
//that function exits after the block
return;
}
> As I understand the example, it was intended to be (and is,
> given current proposals) correct code, given the fact that
> the author knows (for example, because he wrote it) that
> the function throw_my_exception really does throw.
Ii is good, that the author knows, it remains to tell the knowledge to
compiler using C++ rules.
> The
> question is whether your proposal would allow similar code
> to compile cleanly without extra overhead in the source
> code or at runtime.
What kind of overhead can be introduced by my proposal in the case?
> Idioms that are robust for a human
> can be opaque to a compiler;
Wrong idea. Any big program has been written by unknown people where insted
of "throw" used "throw_my_exceprion", insted of "return" used "my_return"
and so on in practically will be impossible to maintain for end-user,
because instead of base C++ conventions some other specific conventions will
be used.
In fact the code is struggling with C++ declatations instead of use them, so
the example is unrelated to problem of moveable - it is not a kind of
problem, created by appearence of moveable data type. A problem, created by
appearence of moveable data type is "double move", for example.
I am using code in practical progrms, that trying to elide termination of
program on "double-throw", but i am forced to follow by C++ rules in the
case of replacement of "throw":
if(err_condition)
{
safe_throw<err_type>(params);
//code of return if throw is impossible
return <any useless value or error_value if return is impossible>;
}
> conservative rules would
> have to either add runtime cost or declare the idiom shown
> above to be invalid, and either would be a shame.
Code must not have UB, and it is not "conservative" and the question of
absence of UB is unrelated to problems of moveable data type.
> (Howard's put a *lot* of time into considering the rvalue
> reference proposals,
And so what? "???????? ??????????" (sorry, do not know english translation)
put a *lot* of time into considering of epicycles based on the fact, the
Earth in flat. Does we need to use the fact of flat Earth? Working with
rvalue reference proposal Howard has spent his time much better than looking
TV and so on, and could find many interesting things suitable in other
applications, unrelated to moveable data type.
Moveable data type based on r-value reference is weak stuff and does not
allow to implement simpest kinds of applications with moveable data type.
For C++ moveable data type can not be implemented as "slave by born" without
the same rights as "const" or "copyable data type".
> and my first assumption if something
> looks odd when I see his rvalue reference-enabled code is
> to assume that I have something to learn.)
Howard's personal properties are unrelated to problems of moveable data
type, especially he can easy change his proposal into correct state. I hope
the personal properties can help him in the work.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Mon, 19 Mar 2007 16:49:10 GMT Raw View
James Dennett wrote:
>
>>>> As I can understand, auto_ptr with move semantics was called
>>>> "unique_ptr", but really they do the same. So do we need new
>>>> name for auto_ptr? I think no.
>>>> ...
>>>> ( i already have listed 6 points of deisagreement with
>>>> the "r-value reference" in the thread and still no one has
>>>> denied my reasons in essence and proved that i was wrong ).
>>>>
>>> Your first point was:
>>>
>>>> 1. No auto_ptr support.
>>>> =======================
>>> And I've reread that point several times. I'm still failing
>>> to see how the rvalue reference package is lacking in this area.
>>
>> In general. if anyone really want find answer (unknown to him), I think,
>> he
>> is forced to answer on _each_ opposite argument in essence. There are no
>> other way of searching (at least i do not know other way).
> By and large, I can say that I could not make any sense
> of most of what you wrote.
In comp.lang.c++ one man have told me, that it is not a good idea to discuss
"the ways of correct discussions" mixed with topic. Maybe he was right, but
only if his opinion is not obstacle to find topic's answers.
I see ( looking on your reply "I can say that I could not make any sense of
most of what you wrote" ) my sentence "he is forced to answer on _each_
opposite argument in essence" has not found a good place in your sole.
I do not care do you agree with me or not, because the my sentence "he is
forced ..." is just translation of well-known rule of formal logic. As
programmer, if you will ignore any rules of formal logic in your programs,
your programs will never do any useful, because to CPU you never can say
"Listen, hell's CPU, I could not make any sense of most of what you doing".
During conversation it is the same, no any useful answer can be found with
refusing from rules of of formal logic, the only useful example of
conversation without the rules of formal logic is one containing no words,
only series of useless curses to address of enemies on square meeting,
producing loud "huraaa" from listeners.
In the my text above I am speaking, that your idea "I can say that I could
not make any sense of most of what you wrote" chiefly pointed against the
rule "he is forced to answer on _each_ opposite argument in essence" rather
than against me or my statements, because in order to disagree with me you
have violated the rule twice:
- did not list concrete error points in my text,
- implicitly said, that point of "misunderstands" is my bad source, not the
rule violation.
It is no any sense to discuss concrete problems without the rules of formal
logic. Also, i can explain the rule in the concrete case of conversation: I
never can guess what part of my statements has been wrong for you, and your
attempts to avoid concrete enumerating at least some of concrete wrong
points in my statemets often can speak that there are no wrong points there,
but you do not agree, so you are forced to search other way of "discussion".
> If so, it will not help to ask them what they "rejected",
> except for the fact that your objections did not seem
> coherent.
I understand: "I do not like it, I can not say why, but probably all are
totally non-coherent, because < here can be any unrelated to provement of
object of discussion >".
> Maybe I can address them somewhat:
>
> 1) "No auto_ptr support"
>
> It wasn't clear what you meant here.
>
Answer to concrete unclear sentences from original post.
> 2) "No ordered definitions
> for "copyable" and "moveable" C++ concepts.
>
> It was not clear what you meant by this, or why you felt
Answer to concrete unclear sentences from original post.
> 3. "Value" is not the same as "reference"
>
> It was not clear what you meant here.
Answer to concrete unclear sentences from original post.
> It's obviously true
> that "value" is not the same as "reference", but that does
> not present a problem for the proposal
I have no problem, so you are wrong.
> 4. "Non-const" is not the same as "moveable".
>
> Again, this is well-known, and not a problem for the
> proposal.
I have no problem, so you are wrong.
> If you believe there is a problem, you will
> need to provide convincing evidence.
http://grizlyk1.narod.ru/cpp_new/#12
> You write that
> "The ownership from auto_ptr can not be transferred
> more than one time" but this is not true; ownership
> can be passed along an unlimited chain of auto_ptr
> objects. Was this maybe not what you meant to write?
The ownership from _concrete object of class of_ auto_ptr can not be
transferred more than once. And context is clear speaking about it :
"Also it is easy to see, that non-const can not protect us from logically
wrong "operator move" has been applied twice to the non-const object (double
move). We can say, that move semantic required from C++ "once" support
rather than "non-const" support, it is really different things."
> This was also a key point in your number 5, which also
> says (incorrectly) that auto_ptr must not be passed by
> reference. Certainly passing auto_ptr by reference is
> unusual, but it can be quite correct.
http://grizlyk1.narod.ru/cpp_new/#11
"Also it means, that there are no more than one auto_ptr with the same
address simultaneously.
Unlike to auto_ptr, we can have many POD pointers with the same address
(that have been placed in an auto_ptr) and we can use the pointers while the
auto_ptr exist."
> 6. Interaction "copyable" and "moveable"
>
> Again, it was not clear what you meant here;
Answer to concrete unclear sentences from original post.
> could you be more explicit?
http://grizlyk1.narod.ru/cpp_new/#14
"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 (enumerate) all strict rules also ("functions
expecting moveable value can use copyable value" and so on). "
> It's possible that these problems are mine, but in general
> I find discussions on comp.std.c++ quite easy to follow
> (sometimes with a little work), so it's likely that if I
> do not see what points you are trying to make then there
> may be others who need more clarity.
>
> I cannot make constructive responses to most of your points
It is a pity, but i can not response instead of you.
> as they seem not to address the rvalue references subject.
Becasue r-value reference is implementation of something, so i am speaking
about the thing, the r-value reference is implementing.
> If you can express your ideas in more concrete detail, showing
> how they actually present difficulties with the current
> proposals in practical situations, you may well find that
> others will support your points.
Answer to concrete unclear sentences from original post, unrelated to the
current
proposals of r-value reference in practical situations.
So, as funny result of the discussion - to be happy is much better to be
unhappy. Speaking seriously, I have made the long explanation in the post in
order to make example and to refer on the example in future, if it will be
nessesary.
--
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 ]
Author: jdennett@acm.org (James Dennett)
Date: Mon, 19 Mar 2007 16:50:30 GMT Raw View
Grizlyk wrote:
> James Dennett wrote:
>>> He has asked me how it can be implemented with my proposal. Try open
>>> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,
>>> lvalue/rvalue has ablsolutely no any sense in context of data type.
>>> Lvalue
>>> means "address can be taken" and nothing more. "Lvalue" is unrelated to
>>> "const", "copyable" or "moveable" data type.
>> The relationship is something that exists and has been
>> considered in quite a lot of detail.
>
> Any term, binding several objects, as relationship do, of course can be
> considered for any combinations of any objects. For example, we can consider
> question about any relationships between C++ and rain in any desert.
But we would not reasonably be able to consider it
"in detail", as there is no significant relationship
between C++ and weather in some specified geographical
region. On the other hand, the relationship between
rvalues and movable items is quite specific and
meaningful, arising from the basic notion that
temporary objects are rvalues (even when their
addresses can be taken), and that moving from a
temporary object is generally safe.
> But the possible ability of consideration is not the same, that the
> considered term can be applied to binding the concrete combination of the
> concrete objects. For example, there are no any relashionship between C++
> and rain in any desert.
Right, so that would not be a useful thing for us to
discuss.
> So original sentence: "there are no any relashionship between "Lvalue" and
> "const", "copyable" or "moveable" data type" is correct statement at least
> formally.
How can it be correct when others have supplied specific
details of the concrete relationship that exists between
rvalues and movability?
(Also note: "rvalue references" do not apply only to
rvalues -- while they bind to rvalues, it is quite
possible and useful to use an rvalue reference to
cause a non-rvalue to be treated in the same way as
an rvalue, such as is done by std::move.)
> And logically the original sentence is also correct, because "Lvalue" means
> "address can be taken, so memory of the expression always exist" and
> speaking nothing related to data type.
Lvalue does not mean that; with user-defined types it is
possible to take the addresses of some rvalues, and taking
the addresses of certain lvalues can be prevented.
> So we can easy imaging at least
> conceptual "moveable" object, address of which can be taken as well as can
> not, so there is "Lvalue moveable" as well as "Rvalue moveable" in C++.
That's true, and the rvalue reference proposal allows for
expressing movement from lvalues via std::move. Do you
think there is an inability to express this with the
current proposals? Are you familiar with std::move?
> Rvalue is not the term that can be used to declare any data type, including
> moveable data type. The fact, that some rvalue expressions looks like
> "moveable" is just accident.
It's not clear to me what you mean here. It's certainly
true that there is a fundamental reason why moving from
temporaries is a reasonable thing; that is not just an
accident.
-- 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 ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Mon, 19 Mar 2007 15:28:31 CST Raw View
on Thu Mar 15 2007, grizlyk1-AT-yandex.ru ("Grizlyk") wrote:
> The auto_ptr always was not copyable (has no copy constructor).
std::auto_ptr<T> has a constructor that can accept a single argument
of std::auto_ptr<T>&. By the definition of "copy constructor" in the
C++ the standard, that is a copy constructor.
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Mon, 19 Mar 2007 15:28:05 CST Raw View
on Mon Mar 19 2007, grizlyk1-AT-yandex.ru ("Grizlyk") wrote:
> I see ( looking on your reply "I can say that I could not make any sense of
> most of what you wrote" ) my sentence "he is forced to answer on _each_
> opposite argument in essence" has not found a good place in your sole.
>
> I do not care do you agree with me or not, because the my sentence "he is
> forced ..." is just translation of well-known rule of formal logic.
Well, not a very good translation, then. Your sentence, "he is forced
to answer on _each_ opposite argument in essence," really is
incomprehensible to me, as I expect it is to most native speakers of
English.
> As programmer, if you will ignore any rules of formal logic in your
> programs, your programs will never do any useful, because to CPU you
> never can say "Listen, hell's CPU, I could not make any sense of
> most of what you doing".
>
> During conversation it is the same, no any useful answer can be
> found with refusing from rules of of formal logic, the only useful
> example of conversation without the rules of formal logic is one
> containing no words, only series of useless curses to address of
> enemies on square meeting, producing loud "huraaa" from listeners.
All the formal logic in the world won't help your argument if your
readers can't parse it. What you intend to say could be the most
brilliant thing ever posted here, but it will have no impact if you
can't make it understandable.
James Dennet writes:
>> If so, it will not help to ask them what they "rejected",
>> except for the fact that your objections did not seem
>> coherent.
>
> I understand: "I do not like it, I can not say why, but probably all
> are totally non-coherent, because < here can be any unrelated to
> provement of object of discussion >".
I don't think it's a matter of like or dislike, but of communication
failure.
<snip>
>> It's obviously true
>> that "value" is not the same as "reference", but that does
>> not present a problem for the proposal
>
> I have no problem, so you are wrong.
Your answer doesn't seem to be consistent with formal (or informal)
logic. James wrote that your statement ("value is not the same as
reference") does not present a problem for the proposal; he didn't
claim that "you have a problem." Your lack of a problem has no
bearing on whether "value is not the same as reference" presents a
problem for the proposal.
So, formally speaking
You have no problem
does not imply
James is wrong
:)
--
Dave Abrahams
Boost Consulting
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.comeaucomputing.com/csc/faq.html ]
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Tue, 13 Mar 2007 17:59:14 CST Raw View
I am trying to resubmit the following lost article from 10 03 2007, 12:36:
Howard Hinnant wrote:
>
>> I can repeat again:
>
> Sorry for making you repeat.
Nothing to sorry, i just have noted, that used the words twice and it is not
error from my side.
>> 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. Correct 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.
Really? Your original code is true "undefined behaviour". It is the same as
the following example:
if (condition)std::move(a1);
std::move(a1);
if "condition" is true, you will get "double move" error. So compiler can
only warn you about the possible error, compiler can not improve your
design.
The previous "double move" error is the same one as error of access to
memory that already has been destroyed by "delete":
if (condition)delete a1;
delete a1;
You must _not_ work with "delete" like in the example and must _not_ write
the same with "std::move()".
Now any could ask: we do not require any "attributes" for "delete", why we
need "attributes" for "moveable"?
Because we want to have _reliable_ "dynamic memory variable" - as well
suitable for usage as "auto memory" does (garbage collector is other way to
make _reliable_ "dynamic memory variable" but (unlike to "moveable") for the
cost of perfomance lost).
The "delete" is _low_ level feature to only mark dynamic memory free, it
does not intend to be the same as "auto memory variable". The "delete" must
be encapsulated into wrapper, and the wrapper already must be the same as
"auto variable", but it can not be done without the "attributes" due to
nature of "moveable data type".
> The if clause might have ended with:
>
> throw_my_exception();
Sorry, i so not understand <what> have ended into "throw_my_exception()".
> I know that this function is never going to return, thus the "else"
> isn't needed.
There are no standard C++ function attribute as "never return". If the
attribute is exist for your compiler, compier will not produce any warnings
here.
> 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".
Again, it is just wrong design, you must not implicitly rely on the fact
that unknow function will never return and must not write like this:
extern char *src;
extern char *dst;
{
if(condition){ dst=0; my_funct(); }
//you think my_funct(); will never return
//so you do not place "else" here
memcpy(dst,src,100);
}
You must decide: either function will return, or will not and write
appropriate code.
Also i have said, that if you are sure, that you never will return from the
true condition branch, but simultaneously do not want to explicit write the
fact with "else", "return", "break" and so on, you can write like this:
if(condition){..}
a1:(ctor);
The "a1:(ctor);" will produce no code, it is compile time directive of
compiler that from the point "a1" will always have "ctor" attribute, in
spite of "if(condition)".
>> 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?
You can move from "moveable" or "copyable", but you must do it in correct
manner. This is the same as you must not working with "copyable" out of its
scope:
{
int a;
a=0;
}
//error "a" is not exist here
a=1;
In fact, the expression "moveable type a2(a1);" is the same as "}" but only
for "a1"
a1:{
>> > A a1
>> > if (foo())
>> > {
>> > A @a2(a1);
a1:}
>> > ...
>> > }
without "else" it can be error: "a1:}" has been executed, there is no "a1"
variable has been declared here
>> > // Has a1 been moved from here?
>> > A @a3(a1); // error or not?
> 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&);
"It&" means "reference to copyable", so you have required much from the type
"It" to be "copyable". Any "moveable" (as auto_ptr) can not be used for the
template.
> template <class It, class T>
> It
> foo(It first, It last, const T& x)
> {
"const T&" means "reference to const copyable", so you have required from
the type "T" to be "copyable". Any "moveable" (as auto_ptr) can not be used
for the template.
> 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.
I can not say any about "rvalue" in the example. All depends from
declarations, for example, from declaration of "It::operator*()".
> To the compiler it may look like I'm moving from the
> same lvalue over and over.
It will be easy to understand, if you will place here all declarations. It
seems to me that you are detecting weak points only dute to declarations are
absent. Compiler can not compile the template at the point of declaration.
All tests for the template can be done only at the point of instantiating.
Place here any instantiateable code.
> Is my above example code:
>
> 1. A compile time error?
> 2. ...
The template can not be instantiating at the point of declaration. There are
no syntax errors if assuming that all undeclared names will be declared
correctly during instantiating. I (and compiler too) can no guess what do
you mean. Too many undeclared things.
Consider:
template<class T>int foo(){ return static_cast<int>(T(0)); }
Is my above example:
1. A compile time error?
2. A warning about undefined behavior?
.
> 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.
1.
The "compile time attributes for moveable" is stuff intended to work cheafly
with auto_ptr-like RAII wrappers, and the "compile time attributes" can not
be appied for all possible runtime conditions.
But in spite of this limitation, "compile time attributes" can help user to
explicitly express what he want to get with the wrapper, and can help to
detect some important errors for it. The stuff is not intended to be "total
protection system", trying to detect all possible holes in your program.
If you will follow the compile time attribute abilities (instead of fight
with them or ignoring them), you will get _reliable_ code similar to this:
{
int a;
a=0;
}
//error "a" is not exist here
a=1;
Also it is important, that we can write compiler with partial support of the
attributes. Compiler for the first step can detect its syntax and silently
ignoring them, so the "integrated moveable concept" (unlike "r-value
reference") is upgradeable.
It is important that "integrated moveable concept" (unlike "r-value
reference") with its keyword "moveable" does not struggle with ordinary C++
style of type declarations and allows to user to express all possible useful
combinations of all types: "const, volatile, moveable, copyable ...".
2.
Note, in your example you are using "It" as a kind of pointer here
"*first++=". Do you want to be shure, that compiler will warn you about the
possible "double move"?
Pointers by its definition is simplest kind of "runtime template". Compiler
can not trace any compile time attributes for runtime templates _even_ for
"copyable data type". Consider:
-- cut here --
#include <stdio.h>
namespace
{
const char *p=0;
void foo()
{
char a[]="hello";
p=a;
printf("My message: %s\n",p);
}
//namespace
}
int main()
{
foo();
//error "*p is not exist here" is not detected
printf("My message: %s\n",p);
}
-- cut here --
Do you want to say, that your programs are just total array of pointers and
you always will use runtime templates? I am not sure.
--
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 ]
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Wed, 14 Mar 2007 10:58:11 CST Raw View
In article <et7a0h$mp0$1@aioe.org>, "Grizlyk" <grizlyk1@yandex.ru>
wrote:
> > The if clause might have ended with:
> >
> > throw_my_exception();
>
> Sorry, i so not understand <what> have ended into "throw_my_exception()".
struct A {...};
A save_state;
void throw_my_exception {throw my_exception();}
void f()
{
A a1;
// ...
if (there_is_an_error)
{
save_state = std::move(a1);
throw_my_exception();
}
// ...
A a2 = std::move(a1); // compile-time error?
// ...
}
> Do you want to say, that your programs are just total array of pointers and
> you always will use runtime templates? I am not sure.
I was trying to express that the use of move semantics for the templated
functions in <algorithm> is an important application. I have gone
through the exercise of implementing <algorithm> and using move in the
appropriate places. I am unclear how your design fares for this task.
Will I need to use the "runtime" keyword to keep the compiler from
flagging an error, either at template definition or instantiation time?
The templated code I showed earlier was a subset of a slightly modified
implementation of std::remove, as coded under the current rvalue
reference proposal.
The code I showed used a helper function: increment(i) to hide the ++i
from the compiler. While this isn't how I coded std::remove, such use
is not unheard of
(http://www.boost.org/libs/iterator/doc/iterator_adaptor.html).
Actually, even without the helper increment() function, the compiler
can't really know what ++i means unless i is a scalar, or it has
immediate access to the definition of operator++() for that type (which
could be in another translation unit or dynamic library).
template <class FwdIt, class T>
FwdIt
remove(FwdIt first, FwdIt last, const T& value)
{
first = std::find(first, last, value);
if (first != last)
{
FwdIt i = first;
while (++i != last)
{
if (!(*i == value))
{
*first = std::move(*i);
++first;
}
}
}
return first;
}
And perhaps this is instantiated with:
FwdIt = std::list<std::string>::iterator
T = std::string
Is this possible with your design? What is the syntax? If it does not
require the "runtime" keyword, why 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 ]
Author: "=?iso-8859-1?q?Pedro_Lamar=E3o?=" <pedro.lamarao@gmail.com>
Date: Wed, 14 Mar 2007 11:00:35 CST Raw View
On 13 mar, 20:59, "Grizlyk" <grizl...@yandex.ru> wrote:
> > template <class It> It& increment(It&);
>
> "It&" means "reference to copyable", so you have required much from the type
> "It" to be "copyable". Any "moveable" (as auto_ptr) can not be used for the
> template.
lt& doesn't mean "reference to copyable", it means "reference to
lvalue".
>
> > template <class It, class T>
> > It
> > foo(It first, It last, const T& x)
> > {
>
> "const T&" means "reference to const copyable", so you have required from
> the type "T" to be "copyable". Any "moveable" (as auto_ptr) can not be used
> for the template.
Just declaring the parameter as const T& doesn't require T to be
Copyable.
The following type:
struct resource {
resource ();
int query (int param) const; // query resource on certain param
private:
resource (resource const&);
resource& operator= (resource const&);
void* stuff;
};
is not Copyable.
Now let me fill in this foo function:
template <typename Iterator, typename T>
Iterator
foo (Iterator begin, Iterator end, T const& t) {
for (; begin != end; ++begin) {
int result = t.query(*begin);
// operate with result somehow.
}
return begin;
}
Now, observe the following:
vector<int> params;
bar b;
foo(params.begin(), params.end(), b);
b is an lvalue binding to a const referente to lvalue, and b is of
type bar, and bar is not Copyable.
That declaration does not require the type bar to be Copyable.
references to lvalues are not necessarily references to values of
Copyable types.
lvalues are lvalues, Copyable types are Copyable types.
--
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 ]
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Wed, 14 Mar 2007 11:38:21 CST Raw View
tasjaevan@gmail.com wrote:
>>
>> Can you give me examples of any other possible values of the expression
>> "auto_ptr(unique_ptr)" in the context: "in most _very_ important cases
>> (as
>> for auto_ptr(unique_ptr))". I do not insist, it is just interesting why
>> "guess" is required here.
>>
>
> I read it as pseudo-C++. I thought you were talking about some kind of
> conversion between the two types.
As I can understand, auto_ptr with move semantics was called "unique_ptr",
but really they do the same. So do we need new name for auto_ptr? I think
no.
>>
>> > It is very important because we will be able to make good
>> > reliable replacement of "garbage collector" _without_
>> > any overhead.
>>
>
> I think we agree that fixing auto_ptr is an important goal of adding
> move semantics to C++. Could you post a use case that unique_ptr does
> not support (in your opinion)?
Probably i do not understanf the question. Without adding move semantics
into C++, reliable auto_ptr can not be implemented, because auto_ptr is not
copyable data type. The "r-value reference" is _not_ best way to add move
semantics because ... ( i already have listed 6 points of deisagreement with
the "r-value reference" in the thread and still no one has denied my reasons
in essence and proved that i was wrong ).
>
> (Also, I should point out that unique_ptr has very little to do with
> garbage collection. It is an important tool for achieving
> *deterministic* destruction - almost the opposite of garbage
> collection)
Maybe, but I am not sure, that anybody has tryed to reach "deterministic
destruction" designing "auto_ptr". As i can understand, the purpose of
"auto_ptr" is hiding explicit memory allocation, as "auto" memory do: we are
declaring auto object of auto_ptr class and its "dynamic" memory (that
auto_ptr owns) looks like "auto" memory. So auto_ptr logically do the same
as garbage collector.
Only difference here that we must explicit separate "ownership" and "POD
memory pointer", so auto_ptr can not hide details of concrete memory type
_with the help of POD pointer_, as integrated to language garbage collector
could do.
Of course, we can declare more advanced (than POD pointer) interface
("holder" or "keeper") that will be suitable for all types of C++ memory:
auto, static, dynamic, dynamic_arrays and possible other and auto_ptr will
be an implementation of the interface. So templates, working with memory via
the interface will be independent from concrete memory type.
But the interface has limitations as any interface do and algorithms (unlike
to POD pointer) must take in account the fact of existing "ownership". In
other side, we have no size overhead in comparison with auto memory:
auto_ptr can be implemented (assuming C++ will support moveable) with data
members of class including only one POD pointer ( sizeof(auto_ptr) ==
sizeof(POD pointer) ). The time of allocation/deallocation depends from
"new" and "delete" implementation. Probably we could implement fast "new"
and "delete" for some extraordinary classes and dynamic nemory under
auto_ptr control for them can be nearly as fast, as auto memory do.
--
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 ]
Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Wed, 14 Mar 2007 17:49:01 GMT Raw View
In article <et8gu7$8ke$1@aioe.org>, "Grizlyk" <grizlyk1@yandex.ru>=20
wrote:
> As I can understand, auto_ptr with move semantics was called "unique_pt=
r",=20
> but really they do the same. So do we need new name for auto_ptr? I thi=
nk=20
> no.
> ...=20
> ( i already have listed 6 points of deisagreement with=20
> the "r-value reference" in the thread and still no one has denied my re=
asons=20
> in essence and proved that i was wrong ).
Your first point was:
> 1. No auto_ptr support.
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
And I've reread that point several times. I'm still failing to see how=20
the rvalue reference package is lacking in this area.
I recently wrote to another forum what I perceive as the major problem=20
with our current auto_ptr and why it needs to be replaced. I am=20
repeating that text here to answer why I believe auto_ptr needs a new=20
name:
My problem with auto_ptr stems from its use as a value_type in=20
sequence-modifying (user-written) generic code. =A0The fear stems from=20
early implementations of std::sort, but I think the same type of problem=20
could occur in other sequence modifying algorithms:
template<class RandomAccessIterator, class Compare>
void
sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
=A0=A0=A0...
=A0=A0=A0// choose a partition element with RandomAccessIterator i
// and store it in a local
=A0=A0=A0value_type median =3D *i;
=A0=A0=A0// Now partition sequence with respect to median
=A0=A0=A0...
=A0=A0=A0// median never assigned back into the range.
// =A0Why would I? *i is still there!
}
Now when you call this with say:
std::auto_ptr<int> my_array[10];
=2E
std::sort(my_array, my_array+10, indirect_less<int>());
then you are likely to get a run time error (i.e. a crash). =A0The cause=20
of the problem is that when the generic code author writes:
=A0=A0=A0value_type median =3D *i;
he's thinking *copy*. =A0*i should remain unchanged in his mind. =A0But w=
hen=20
the type of *i is auto_ptr, then sort's author's assumptions are=20
incorrect.
So who's wrong? =A0The author of the generic code for believing that:
=A0=A0=A0value_type median =3D *i;
is a copy? =A0Or is the author of type who allows a mutating copy from an=
=20
lvalue wrong?
My belief is the latter. =A0So "fixing auto_ptr" would involve changing i=
t=20
such that:
=A0=A0=A0value_type median =3D *i;
causes a compile time error (to prevent the run time error in the=20
generic code). =A0In non-generic code, this means that:
auto_ptr<A> p1;
auto_ptr<A> p2 =3D p1; =A0// must not compile
But I do not believe we can apply this fix to auto_ptr because of=20
backwards compatibility concerns. =A0Instead, people who are willing to=20
take the backwards compatibility hit will vote by changing their usage=20
to unique_ptr (which is essentially just an auto_ptr with the mutating=20
copy disabled -- from lvalues only).
So, suggestions for "fixing auto_ptr" should really be clear about=20
exactly what is being fixed, and what that cost is in terms of backwards=20
compatibility is. =A0Imho, no matter what we do to fix it, if it moves=20
from lvalues with copy syntax, then the very biggest problem with it=20
hasn't been fixed. =A0Any other problems auto_ptr may have are trivial=20
annoyances in comparison.
For more details on the auto_ptr/unique_ptr issues, please see:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html#20.4.5
%20-%20Class%20template%20auto_ptr
-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 ]
Author: tasjaevan@gmail.com
Date: Wed, 14 Mar 2007 13:51:33 CST Raw View
On Mar 14, 5:38 pm, "Grizlyk" <grizl...@yandex.ru> wrote:
> tasjae...@gmail.com wrote:
>
> As I can understand, auto_ptr with move semantics was called "unique_ptr",
> but really they do the same. So do we need new name for auto_ptr? I think
> no.
>
Giving auto_ptr move semantics may break existing code.
>
> > I think we agree that fixing auto_ptr is an important goal of adding
> > move semantics to C++. Could you post a use case that unique_ptr does
> > not support (in your opinion)?
>
> Probably i do not understanf the question. Without adding move semantics
> into C++, reliable auto_ptr can not be implemented, because auto_ptr is not
> copyable data type. The "r-value reference" is _not_ best way to add move
> semantics because ... ( i already have listed 6 points of deisagreement with
> the "r-value reference" in the thread and still no one has denied my reasons
> in essence and proved that i was wrong ).
>
Those points have not been answered because they were based on a mis-
understanding of how rvalue references work.
To make your point, please post what you think should be possible with
auto_ptr, but isn't possible with unique_ptr as proposed.
>
> > (Also, I should point out that unique_ptr has very little to do with
> > garbage collection. It is an important tool for achieving
> > *deterministic* destruction - almost the opposite of garbage
> > collection)
>
> Maybe, but I am not sure, that anybody has tryed to reach "deterministic
> destruction" designing "auto_ptr". As i can understand, the purpose of
> "auto_ptr" is hiding explicit memory allocation, as "auto" memory do: we are
> declaring auto object of auto_ptr class and its "dynamic" memory (that
> auto_ptr owns) looks like "auto" memory. So auto_ptr logically do the same
> as garbage collector.
>
Garbage collection has the same effect as auto_ptr only in a specific
case:
a) the object's destructor only frees memory and
b) there is only one pointer to the object
In my experience, auto_ptr (and other smart pointers) are used to
manage ownership of non-stack objects. Nothing to do with memory
directly.
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Thu, 15 Mar 2007 14:53:30 GMT Raw View
Howard Hinnant wrote:
>
>> > The if clause might have ended with:
>> >
>> > throw_my_exception();
>>
>> Sorry, i so not understand <what> have ended into "throw_my_exception()".
>
> struct A {...};
> A save_state;
>
> void throw_my_exception {throw my_exception();}
>
> void f()
> {
> A a1;
> // ...
> if (there_is_an_error)
> {
> save_state = std::move(a1);
> throw_my_exception();
> }
> // ...
> A a2 = std::move(a1); // compile-time error?
> // ...
> }
I was suspecting it. This is a case when you rely on unknown implementation
of "throw_my_exception()", that the function will never return. You probably
think compiler must take the case into account for moveable (in spite it
will not work even with copyable) and you must not explicit tell to compiler
about the fact. The accident has been considered by me:
>>You must decide: either function will return, or will not and
>>write appropriate code.
What do you think about the consideration (skipped by you)?
>> Do you want to say, that your programs are just total array of pointers
>> and
>> you always will use runtime templates? I am not sure.
>
> I was trying to express that the use of move semantics for the templated
> functions in <algorithm> is an important application.
I do not argue that "move semantics is important", but
> I have gone
> through the exercise of implementing <algorithm> and using move in the
> appropriate places. I am unclear how your design fares for this task.
>
> Will I need to use the "runtime" keyword to keep the compiler from
> flagging an error, either at template definition or instantiation time?
>
runtime templates can _not_ be controlled in compile time _even for
copyable_. I have written:
>> 2.
>> Note, in your example you are using "It" as a kind of pointer here
>> "*first++=". Do you want to be shure, that compiler will warn you about
>> the
>> possible "double move"?
>>
>> Pointers by its definition is simplest kind of "runtime template".
>> Compiler
>> can not trace any compile time attributes for runtime templates _even_
>> for
>> "copyable data type". Consider:
What do you think about the consideration?
In other words, "moveable data type" can not make the case worse than
copyable do. The purpose of compile time attributes is not control data
hidden by pointers, but to make auto memory and dynamic memory equal.
One can see the steps of "moveable concept" appearence:
*******************************************************
1. Local holder.
================
I have some "holders" (practically using in my programs) to make correct
destruction of dynamic memory on errors or returns. Its memory must be used
only locally in the block:
extern uint field_size;
void get(char *const);
uint read(const char *const);
{
int a(1);
obj_holder<int> b(new int);
array_holder<char> c(new char[field_size]);
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}
There is a problem here: unlike "a", i can not return address of "b" or "c"
outside of the local block. At the "}" destructors of the "holders" will
free its dynamic memory.
2. Moveable concept.
====================
To solve the last problem, we can add "ownership" term into "holder" and
define concrete "ownership transfer" behaviour.
The example of the "concrete ownership transfer behaviour" is auto_ptr
behaviour. The purpose of the auto_ptr to pass ownership to the place of
destanation in spite of auto blocks bounds.
The often application of auto_ptr's ownership transfer is one from unnamed
temporary source to named destanation variable, that is why we no need any
runtime tests to share ownership between some local blocks, because unnamed
temporary unaccessible and will be automatically deleted after transfer has
been completed.
So the kind of "pass" is "move" for auto_ptr. For auto_ptr we can not do
"copy", that is why auto_ptr is not copyable, but moveable. In order to
allow to user to express the fact of moveable data type we need "moveable"
keyword, that can be applied similarly to "const" or "volatile" keywords. We
can not use only "moveable value" or "moveable reference" instead of
ordinary moveable data type.
Of course, we can use auto_ptr with named source variable also, like this:
{
int sa(1);
auto_obj<int> sb(new int(2));
auto_array<char> sc(new char[field_size]);
{
int a(sa);
auto_obj<int> b(sb);
auto_array<char> c(sc);
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}}
There is no problem of access of named source variable when internal block
has been executed here due to "}}" - named source variable is never used
after transfer has been completed.
But it is easy to see, that named source variable is accessible inside
internal block and between "}" in "}}". The access to named source variable
after move has been done is _always error_, never UB.
3. Compile time attributes for moveable data type.
==================================================
The cause of last error is the fact, that boundaries of blocks for "auto"
and "dynamic" memory are not coincide. Take in account, that "non-const"
applied to copyable can not help us to solve the problem, can not protect us
from access to named source variable after move has been done.
To work with "moveable" we must take in account presence of "ownership",
that does not exist for "copyable", so algorithms _can not begin to support
moveable data type_ only by adding "r-value reference" declaration -
algorithms must be _re-designed_ as they must be _re-designed_ to support
"const".
Whithout strict compiler support of detection of improper usage of moveable
data type, it will be _hard to re-design_ old existing code to support new
moveable data type, as it will be hard to re-design old existing code to
support new "const" data type if compiler will not detect "assignment to
const" error.
The purpose of "compile time attributes for moveable data type" is
attenuation boundaries of blocks for "auto" and "dynamic" memory. By nature
of dynamic memory the life-time of variables belonging to the memory is not
conjunction with ordinary blocks boundaries, controlled by compiler.
We are using the dynamic memory to make a kind of blocks for variables
across ordinary blocks boundaries, because we no need to do "copy" to pass
the variable across any ordinary block boundary, so we increase perfomans
here. But simultaneously we do not want to lose reliability and "compile
time attributes for moveable data type" makes this.
With "compile time attributes for moveable data type" the last example
logically looks like this:
{
sa:{
int sa(1);
sb:{
auto_obj<int> sb(new int(2));
sc:{
auto_array<char> sc(new char[field_size]);
{
int a(sa);
sa:}
auto_obj<int> b(sb);
sb:}
auto_array<char> c(sc);
sc:}
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}
sc:{
auto_array<char> sc(new char[field_size]);
sc:}
}
Now we have no errors. Technically, life-time of moveable will be in
accordance with ordinary boundaries "{}", but logically moveable will be
accessible from C++ only inside its logical boundaries "variable_name:{
variable_name:}".
The sintax "variable_name:{ variable_name:}" can be suitable also, but this
can not replace compile time attibutes - declaring the logical boundaries
implicitly by class or function declaration.
outcome:
No one "r-value reference" can solve the 3 steps due to quietly ignoring
existence of the problems, "r-value reference" is too simple to help us (it
implements only small part of possible moveable data type properties, but
hard to upgrade).
*******************************************************
> The templated code I showed earlier was a subset of a slightly modified
> implementation of std::remove, as coded under the current rvalue
> reference proposal.
>
> The code I showed used a helper function: increment(i) to hide the ++i
> from the compiler. While this isn't how I coded std::remove, such use
> is not unheard of
> (http://www.boost.org/libs/iterator/doc/iterator_adaptor.html).
>
> Actually, even without the helper increment() function, the compiler
> can't really know what ++i means unless i is a scalar, or it has
> immediate access to the definition of operator++() for that type (which
> could be in another translation unit or dynamic library).
Again: you are mixing "moveable data type" and template instantiating. "The
compiler can't really know what ++i means" because the template can not be
instantiated at the point of declaration, but in the point of instantiating
compiler will detect all possible errors correctly.
With the help of "moveable" keyword and syntax of "attributes" you can do
all what C++ can do, there are no any limitations, just try to express what
you want, what is really stored in your mind - compiler will detects most of
your errors.
I can not guess it and probably i do not know all possible applications of
"moveable" keyword and syntax of "attributes", due to this is concept
(paradigm, idiom etc), not concrete way, similarly i do not know all
possible situations with "const" usage.
Maybe you are speaking about local attribute overriding? Do you want to
write template with concrete attribute requirements, overriding declared one
in class?
Also "attributes of moveable data type" can not make your example worse than
copyable do. The compiler can't really know what "*i++" means even for
copyable due to pointer, not due to moveable. The purpose of compile time
attributes is not control data hidden by pointers, but to make auto memory
and dynamic memory equal.
>
> template <class FwdIt, class T>
> FwdIt
> remove(FwdIt first, FwdIt last, const T& value)
again: it is declaration of "copyable" data type "FwdIt" and "T". There are
no any attributes needed here.
> {
> first = std::find(first, last, value);
> if (first != last)
> {
> FwdIt i = first;
> while (++i != last)
> {
> if (!(*i == value))
> {
> *first = std::move(*i);
Maybe you want to have with "std::move" local type override here: to force
copyable "*first" to use "move assignment" instead of "copy assignment"?
If "move assignment" undeclared for the concrete copyable "*first", then its
"copy assignment" will be used instead of "move assignment", no real move
will be done and no any attributes needed.
Assuming "move assignment" declared or "*first" points to true moveable data
type.
Maybe you want to protect "std::move(*i)" double move?
{
*first = std::move(*i);
//do you want error detection here?
*i;
++first;
}
again: "compile time attributes for moveable data type" can not make the
case worse than copyable do. The compiler can't really know what "*i++"
means even for copyable only due to _pointer_, not due to moveable.
You probably can to declare here "moveable_iterator" for FwdIt to make sharp
differences between copyable and moveable data types. I think we must not
declare "*first" as "copyable" if you allow "*first" to be moveable only.
The declarations can be like this:
//"base" of moveable data type
class moveable_class
{
public:
//all moveable can declare the type "internal_state"
//class internal_state;
//here "internal_state" is the same as "self class"
typedef moveable moveable_class internal_state;
// for auto_ptr-like wrapper "internal_state" is stored POD
// pointer it is unsafe if exception will occure while
// "internal_state" does not bind to wrapper
// typedef T memory* internal_state;
// "operator move" returns "moveable value"
// of "internal state" its usage is overhead
// in comparison with direct assignment
// and can be unsafe
moveable internal_state
operator< ()dtor{}
public:
moveable_class(){}
//cast from internal_state
moveable_class(const moveable internal_state&:(ctor;dtor)){}
//:(ctor;dtor) by default for "move ctor"
moveable_class(const moveable moveable_class& :(ctor;dtor)){}
//:(ctor;...) and :(ctor;dtor) by default for "move assignment"
moveable moveable_class&:(ctor;...)
operator=(const moveable moveable_class& :(ctor;dtor))ctor
{return *this;}
private:
//not copyable
moveable_class(const moveable_class&);
moveable_class& operator=(const moveable_class&);
};
//moveable_iterator
template<class T=moveable_class>
class moveable_iterator
{
moveable T auto*:(...;...) data;
public:
//here "operator++" allow to do "<i++"
moveable moveable_iterator&:(ctor;...)
operator++ ()ctor;
moveable moveable_iterator
operator++ (const int)ctor;
//moveable reference without attributes
moveable T& operator* (){ return *data; }
//moveable reference without without explicit attributes
//by default means "the attributes can not be changed"
//moveable T&:(same;same)
//("move ctor" and "move assignment" is exception)
//operator move
moveable T::internal_state
operator< ()dtor { return <*data; }
public:
...
};
Take a look, you must not use "operator*" instead "operator<" to make move.
There are differense between "get POD pointer" and "move ownership".
Now you can be protected from double move for each step
{
*first = <i;
//error detected
*i;
++first;
//ok
*i;
}
> ++first;
> }
> }
> }
> return first;
> }
>
> And perhaps this is instantiated with:
>
> FwdIt = std::list<std::string>::iterator
> T = std::string
As i know, std::list<T>::iterator and std::string have no moveable support.
There is no one declaration of moveable classes here.
>
> Is this possible with your design? What is the syntax?
> If it does not require the "runtime" keyword, why not?
There is no one declaration of moveable classes here, only copyable, i can
not answer to the kind of question related to undeclared classes. Also
"compile time attributes for moveable data type" can not make the case worse
or better than copyable do.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Thu, 15 Mar 2007 14:58:45 GMT Raw View
Howard Hinnant wrote:
>
>> > The if clause might have ended with:
>> >
>> > throw_my_exception();
>>
>> Sorry, i so not understand <what> have ended into "throw_my_exception()".
>
> struct A {...};
> A save_state;
>
> void throw_my_exception {throw my_exception();}
>
> void f()
> {
> A a1;
> // ...
> if (there_is_an_error)
> {
> save_state = std::move(a1);
> throw_my_exception();
> }
> // ...
> A a2 = std::move(a1); // compile-time error?
> // ...
> }
I was suspecting it. This is a case when you rely on unknown implementation
of "throw_my_exception()", that the function will never return. You probably
think compiler must take the case into account for moveable (in spite it
will not work even with copyable) and you must not explicit tell to compiler
about the fact. The accident has been considered by me:
>>You must decide: either function will return, or will not and
>>write appropriate code.
What do you think about the consideration (skipped by you)?
>> Do you want to say, that your programs are just total array of pointers
>> and
>> you always will use runtime templates? I am not sure.
>
> I was trying to express that the use of move semantics for the templated
> functions in <algorithm> is an important application.
I do not argue that "move semantics is important", but
> I have gone
> through the exercise of implementing <algorithm> and using move in the
> appropriate places. I am unclear how your design fares for this task.
>
> Will I need to use the "runtime" keyword to keep the compiler from
> flagging an error, either at template definition or instantiation time?
>
runtime templates can _not_ be controlled in compile time _even for
copyable_. I have written:
>> 2.
>> Note, in your example you are using "It" as a kind of pointer here
>> "*first++=". Do you want to be shure, that compiler will warn you about
>> the
>> possible "double move"?
>>
>> Pointers by its definition is simplest kind of "runtime template".
>> Compiler
>> can not trace any compile time attributes for runtime templates _even_
>> for
>> "copyable data type". Consider:
What do you think about the consideration?
In other words, "moveable data type" can not make the case worse than
copyable do. The purpose of compile time attributes is not control data
hidden by pointers, but to make auto memory and dynamic memory equal.
One can see the steps of "moveable concept" appearence:
*******************************************************
1. Local holder.
================
I have some "holders" (practically using in my programs) to make correct
destruction of dynamic memory on errors or returns. Its memory must be used
only locally in the block:
extern uint field_size;
void get(char *const);
uint read(const char *const);
{
int a(1);
obj_holder<int> b(new int);
array_holder<char> c(new char[field_size]);
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}
There is a problem here: unlike "a", i can not return address of "b" or "c"
outside of the local block. At the "}" destructors of the "holders" will
free its dynamic memory.
2. Moveable concept.
====================
To solve the last problem, we can add "ownership" term into "holder" and
define concrete "ownership transfer" behaviour.
The example of the "concrete ownership transfer behaviour" is auto_ptr
behaviour. The purpose of the auto_ptr to pass ownership to the place of
destanation in spite of auto blocks bounds.
The often application of auto_ptr's ownership transfer is one from unnamed
temporary source to named destanation variable, that is why we no need any
runtime tests to share ownership between some local blocks, because unnamed
temporary unaccessible and will be automatically deleted after transfer has
been completed.
So the kind of "pass" is "move" for auto_ptr. For auto_ptr we can not do
"copy", that is why auto_ptr is not copyable, but moveable. In order to
allow to user to express the fact of moveable data type we need "moveable"
keyword, that can be applied similarly to "const" or "volatile" keywords. We
can not use only "moveable value" or "moveable reference" instead of
ordinary moveable data type.
Of course, we can use auto_ptr with named source variable also, like this:
{
int sa(1);
auto_obj<int> sb(new int(2));
auto_array<char> sc(new char[field_size]);
{
int a(sa);
auto_obj<int> b(sb);
auto_array<char> c(sc);
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}}
There is no problem of access of named source variable when internal block
has been executed here due to "}}" - named source variable is never used
after transfer has been completed.
But it is easy to see, that named source variable is accessible inside
internal block and between "}" in "}}". The access to named source variable
after move has been done is _always error_, never UB.
3. Compile time attributes for moveable data type.
==================================================
The cause of last error is the fact, that boundaries of blocks for "auto"
and "dynamic" memory are not coincide. Take in account, that "non-const"
applied to copyable can not help us to solve the problem, can not protect us
from access to named source variable after move has been done.
To work with "moveable" we must take in account presence of "ownership",
that does not exist for "copyable", so algorithms _can not begin to support
moveable data type_ only by adding "r-value reference" declaration -
algorithms must be _re-designed_ as they must be _re-designed_ to support
"const".
Whithout strict compiler support of detection of improper usage of moveable
data type, it will be _hard to re-design_ old existing code to support new
moveable data type, as it will be hard to re-design old existing code to
support new "const" data type if compiler will not detect "assignment to
const" error.
The purpose of "compile time attributes for moveable data type" is
attenuation boundaries of blocks for "auto" and "dynamic" memory. By nature
of dynamic memory the life-time of variables belonging to the memory is not
conjunction with ordinary blocks boundaries, controlled by compiler.
We are using the dynamic memory to make a kind of blocks for variables
across ordinary blocks boundaries, because we no need to do "copy" to pass
the variable across any ordinary block boundary, so we increase perfomans
here. But simultaneously we do not want to lose reliability and "compile
time attributes for moveable data type" makes this.
With "compile time attributes for moveable data type" the last example
logically looks like this:
{
sa:{
int sa(1);
sb:{
auto_obj<int> sb(new int(2));
sc:{
auto_array<char> sc(new char[field_size]);
{
int a(sa);
sa:}
auto_obj<int> b(sb);
sb:}
auto_array<char> c(sc);
sc:}
get(*c);
if(!*c)safe_throw<err_zptr>("no input string");
*b=read(*c);
if(!*b)break;
for(uint i=*b; i; --i)++a;
return a;
}
sc:{
auto_array<char> sc(new char[field_size]);
sc:}
}
Now we have no errors. Technically, life-time of moveable will be in
accordance with ordinary boundaries "{}", but logically moveable will be
accessible from C++ only inside its logical boundaries "variable_name:{
variable_name:}".
The sintax "variable_name:{ variable_name:}" can be suitable also, but this
can not replace compile time attibutes - declaring the logical boundaries
implicitly by class or function declaration.
outcome:
No one "r-value reference" can solve the 3 steps due to quietly ignoring
existence of the problems, "r-value reference" is too simple to help us (it
implements only small part of possible moveable data type properties, but
hard to upgrade).
*******************************************************
> The templated code I showed earlier was a subset of a slightly modified
> implementation of std::remove, as coded under the current rvalue
> reference proposal.
>
> The code I showed used a helper function: increment(i) to hide the ++i
> from the compiler. While this isn't how I coded std::remove, such use
> is not unheard of
> (http://www.boost.org/libs/iterator/doc/iterator_adaptor.html).
>
> Actually, even without the helper increment() function, the compiler
> can't really know what ++i means unless i is a scalar, or it has
> immediate access to the definition of operator++() for that type (which
> could be in another translation unit or dynamic library).
Again: you are mixing "moveable data type" and template instantiating. "The
compiler can't really know what ++i means" because the template can not be
instantiated at the point of declaration, but in the point of instantiating
compiler will detect all possible errors correctly.
With the help of "moveable" keyword and syntax of "attributes" you can do
all what C++ can do, there are no any limitations, just try to express what
you want, what is really stored in your mind - compiler will detects most of
your errors.
I can not guess it and probably i do not know all possible applications of
"moveable" keyword and syntax of "attributes", due to this is concept
(paradigm, idiom etc), not concrete way, similarly i do not know all
possible situations with "const" usage.
Maybe you are speaking about local attribute overriding? Do you want to
write template with concrete attribute requirements, overriding declared one
in class?
Also "attributes of moveable data type" can not make your example worse than
copyable do. The compiler can't really know what "*i++" means even for
copyable due to pointer, not due to moveable. The purpose of compile time
attributes is not control data hidden by pointers, but to make auto memory
and dynamic memory equal.
>
> template <class FwdIt, class T>
> FwdIt
> remove(FwdIt first, FwdIt last, const T& value)
again: it is declaration of "copyable" data type "FwdIt" and "T". There are
no any attributes needed here.
> {
> first = std::find(first, last, value);
> if (first != last)
> {
> FwdIt i = first;
> while (++i != last)
> {
> if (!(*i == value))
> {
> *first = std::move(*i);
Maybe you want to have with "std::move" local type override here: to force
copyable "*first" to use "move assignment" instead of "copy assignment"?
If "move assignment" undeclared for the concrete copyable "*first", then its
"copy assignment" will be used instead of "move assignment", no real move
will be done and no any attributes needed.
Assuming "move assignment" declared or "*first" points to true moveable data
type.
Maybe you want to protect "std::move(*i)" double move?
{
*first = std::move(*i);
//do you want error detection here?
*i;
++first;
}
again: "compile time attributes for moveable data type" can not make the
case worse than copyable do. The compiler can't really know what "*i++"
means even for copyable only due to _pointer_, not due to moveable.
You probably can to declare here "moveable_iterator" for FwdIt to make sharp
differences between copyable and moveable data types. I think we must not
declare "*first" as "copyable" if you allow "*first" to be moveable only.
The declarations can be like this:
//"base" of moveable data type
class moveable_class
{
public:
//all moveable can declare the type "internal_state"
//class internal_state;
//here "internal_state" is the same as "self class"
typedef moveable moveable_class internal_state;
// for auto_ptr-like wrapper "internal_state" is stored POD
// pointer it is unsafe if exception will occure while
// "internal_state" does not bind to wrapper
// typedef T memory* internal_state;
// "operator move" returns "moveable value"
// of "internal state" its usage is overhead
// in comparison with direct assignment
// and can be unsafe
moveable internal_state
operator< ()dtor{}
public:
moveable_class(){}
//cast from internal_state
moveable_class(const moveable internal_state&:(ctor;dtor)){}
//:(ctor;dtor) by default for "move ctor"
moveable_class(const moveable moveable_class& :(ctor;dtor)){}
//:(ctor;...) and :(ctor;dtor) by default for "move assignment"
moveable moveable_class&:(ctor;...)
operator=(const moveable moveable_class& :(ctor;dtor))ctor
{return *this;}
private:
//not copyable
moveable_class(const moveable_class&);
moveable_class& operator=(const moveable_class&);
};
//moveable_iterator
template<class T=moveable_class>
class moveable_iterator
{
moveable T auto*:(...;...) data;
public:
//here "operator++" allow to do "<i++"
moveable moveable_iterator&:(ctor;...)
operator++ ()ctor;
moveable moveable_iterator
operator++ (const int)ctor;
//moveable reference without attributes
moveable T& operator* (){ return *data; }
//moveable reference without without explicit attributes
//by default means "the attributes can not be changed"
//moveable T&:(same;same)
//("move ctor" and "move assignment" is exception)
//operator move
moveable T::internal_state
operator< ()dtor { return <*data; }
public:
...
};
Take a look, you must not use "operator*" instead "operator<" to make move.
There are differense between "get POD pointer" and "move ownership".
Now you can be protected from double move for each step
{
*first = <i;
//error detected
*i;
++first;
//ok
*i;
}
> ++first;
> }
> }
> }
> return first;
> }
>
> And perhaps this is instantiated with:
>
> FwdIt = std::list<std::string>::iterator
> T = std::string
As i know, std::list<T>::iterator and std::string have no moveable support.
There is no one declaration of moveable classes here.
>
> Is this possible with your design? What is the syntax?
> If it does not require the "runtime" keyword, why not?
There is no one declaration of moveable classes here, only copyable, i can
not answer to the kind of question related to undeclared classes. Also
"compile time attributes for moveable data type" can not make the case worse
or better than copyable do.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Thu, 15 Mar 2007 15:00:13 GMT Raw View
tasjaevan@gmail.com wrote:
>>
>> As I can understand, auto_ptr with move semantics was called
>> "unique_ptr",
>> but really they do the same. So do we need new name for auto_ptr? I think
>> no.
>>
>
> Giving auto_ptr move semantics may break existing code.
What kind of break? The auto_ptr always was not copyable (has no copy
constructor). The little correction _must_ be done to make auto_ptr usage
less dangerous (probably some errors will be found). The correction is only
adding "moveable" to auto_ptr returned and passed by value or reference. All
existing correct moveable usage must not require any more changes. Also
people can write "using old_std::auto_ptr;" and continue to collect runtime
errors.
>
>>
>> > I think we agree that fixing auto_ptr is an important goal of adding
>> > move semantics to C++. Could you post a use case that unique_ptr does
>> > not support (in your opinion)?
>>
>> Probably i do not understand the question. Without adding move semantics
>> into C++, reliable auto_ptr can not be implemented, because auto_ptr is
>> not
>> copyable data type. The "r-value reference" is _not_ best way to add move
>> semantics because ... ( i already have listed 6 points of deisagreement
>> with
>> the "r-value reference" in the thread and still no one has denied my
>> reasons
>> in essence and proved that i was wrong ).
>>
>
> Those points have not been answered because they were based on a mis-
> understanding of how rvalue references work.
So i am just fool, can not understand good thing. It is so easy, that no one
even can explain it more than "they were based on a mis-understanding"
instead answering on concrete questions in essence.
> To make your point, please post what you think should be possible with
> auto_ptr, but isn't possible with unique_ptr as proposed.
I already have listed 6 points of deisagreement with the "r-value reference"
in the thread and this is exact answer on your question. If you will reply
on each of the deisagreement you will see the answer on your question.
>>
>> > (Also, I should point out that unique_ptr has very little to do with
>> > garbage collection. It is an important tool for achieving
>> > *deterministic* destruction - almost the opposite of garbage
>> > collection)
>>
>> Maybe, but I am not sure, that anybody has tryed to reach "deterministic
>> destruction" designing "auto_ptr". As i can understand, the purpose of
>> "auto_ptr" is hiding explicit memory allocation, as "auto" memory do: we
>> are
>> declaring auto object of auto_ptr class and its "dynamic" memory (that
>> auto_ptr owns) looks like "auto" memory. So auto_ptr logically do the
>> same
>> as garbage collector.
>>
>
> Garbage collection has the same effect as auto_ptr only in a specific
> case:
>
> a) the object's destructor only frees memory and
You must not use ctor/dtor for any hidden activity instead of support of
creation of objects.
I hope, we will see in C++ different optimisation for data and code and will
see pipeline executable code with explicit "sequence points".
In the case you never will know concrete point of you non-sequence data
creation. And all required constructor must be declared, but will no
garantee that some implicit of them will not be optimized out.
> b) there is only one pointer to the object
You are confusing with POD pointer and RAII wrapper behaviours. See here:
http://www.hackcraft.net/raii . Auto_ptr is wrapper (ordinary user defined
class) and is not intended to be POD pointer.
--
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Thu, 15 Mar 2007 17:50:36 GMT Raw View
Pedro Lamar=E3o wrote:
>
>> > template <class It> It& increment(It&);
>>
>> "It&" means "reference to copyable", so you have required much from th=
e=20
>> type
>> "It" to be "copyable". Any "moveable" (as auto_ptr) can not be used fo=
r=20
>> the
>> template.
>
> lt& doesn't mean "reference to copyable", it means "reference to
> lvalue".
He has asked me how it can be implemented with my proposal. Try open=20
http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,=20
lvalue/rvalue has ablsolutely no any sense in context of data type. Lvalu=
e=20
means "address can be taken" and nothing more. "Lvalue" is unrelated to=20
"const", "copyable" or "moveable" data type.
As i can understand, temporary can not be assigned to "non-const referenc=
e"=20
only due to the reference can be passed out of the temporary scope and=20
writing into non-existing stack of the terminated function for some peopl=
e=20
looks like more dangerous when reading from the non-existing memory or=20
calling functions with random entry point, that can be done with the=20
temporary assigned to "const reference".
>>
>> > template <class It, class T>
>> > It
>> > foo(It first, It last, const T& x)
>> > {
>>
>> "const T&" means "reference to const copyable", so you have required f=
rom
>> the type "T" to be "copyable". Any "moveable" (as auto_ptr) can not be=
=20
>> used
>> for the template.
>
> Just declaring the parameter as const T& doesn't require T to be
> Copyable.
Who does argue? In order to declare moveable parameter we need write "con=
st=20
moveable T&", It means "reference to const moveable". Or we need write=20
"moveable T&", It means "reference to moveable".
> The following type:
>
> struct resource {
> resource ();
> int query (int param) const; // query resource on certain param
Are you trying to change "param"?
> private:
> resource (resource const&);
> resource& operator=3D (resource const&);
> void* stuff;
> };
>
> is not Copyable.
I agree, because "copy constructor" is private.
> Now let me fill in this foo function:
>
> template <typename Iterator, typename T>
> Iterator
> foo (Iterator begin, Iterator end, T const& t) {
You have required "Iterator" and "T" to be copyable.
> for (; begin !=3D end; ++begin) {
> int result =3D t.query(*begin);
> // operate with result somehow.
> }
> return begin;
> }
But you have never used the requirement for "T" in foo<>.
>
> Now, observe the following:
>
> vector<int> params;
> bar b;
> foo(params.begin(), params.end(), b);
>
> b is an lvalue binding to a const referente to lvalue,
b is copyable lvalue binding to a const reference to copyable
> and b is of type bar, and bar is not Copyable.
In spite the "bar" is undeclared, i trust you.
> That declaration does not require the type bar to be Copyable.
Because you have never used the requirement to be copyable for "T" in foo=
<>.
> references to lvalues are not necessarily references to values of
> Copyable types.
There are no reference to lavalue in the my proposals. Reference to=20
non-copyable (simultaneously non-moveable) can not be explicitly declared=
.=20
Do you need the declaration?
--=20
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 ]
Author: James Dennett <jdennett@acm.org>
Date: Fri, 16 Mar 2007 09:09:45 CST Raw View
Grizlyk wrote:
> Pedro Lamar o wrote:
>>>> template <class It> It& increment(It&);
>>> "It&" means "reference to copyable", so you have required much from the
>>> type
>>> "It" to be "copyable". Any "moveable" (as auto_ptr) can not be used for
>>> the
>>> template.
>> lt& doesn't mean "reference to copyable", it means "reference to
>> lvalue".
>
> He has asked me how it can be implemented with my proposal. Try open
> http://grizlyk1.narod.ru/cpp_new and find there words "lvalue". Really,
> lvalue/rvalue has ablsolutely no any sense in context of data type. Lvalue
> means "address can be taken" and nothing more. "Lvalue" is unrelated to
> "const", "copyable" or "moveable" data type.
The relationship is something that exists and has been
considered in quite a lot of detail. For example, it
is usually safe to move from a temporary object (which
is of course an rvalue). There are other connections;
there are no const rvalues of builtin types, but an
lvalue of type int const is quite a reasonable thing.
There are those who attempt to apply terminology from
other areas to C++, and find that it doesn't fit well;
that's not entirely surprising. By some definitions
C++'s type system is not a "type system" -- which is
all very well, but doesn't make a piece of difference
to the fact that C++ does have a system for types, and
it is a useful one.
-- 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 ]
Author: jdennett@acm.org (James Dennett)
Date: Fri, 16 Mar 2007 14:09:35 GMT Raw View
Grizlyk wrote:
> Howard Hinnant wrote:
>>>> The if clause might have ended with:
>>>>
>>>> throw_my_exception();
>>> Sorry, i so not understand <what> have ended into "throw_my_exception()".
>> struct A {...};
>> A save_state;
>>
>> void throw_my_exception {throw my_exception();}
>>
>> void f()
>> {
>> A a1;
>> // ...
>> if (there_is_an_error)
>> {
>> save_state = std::move(a1);
>> throw_my_exception();
>> }
>> // ...
>> A a2 = std::move(a1); // compile-time error?
>> // ...
>> }
>
> I was suspecting it. This is a case when you rely on unknown implementation
> of "throw_my_exception()", that the function will never return. You probably
> think compiler must take the case into account for moveable (in spite it
> will not work even with copyable) and you must not explicit tell to compiler
> about the fact.
This is not a case of relying on an unknown implementation;
the code is very explicit, it detected an error and it
called a function to throw an exception. Clear and correct
for a human; unknowable to a compiler in general as the
implementation of throw_my_exception may not be available
to it.
As I understand the example, it was intended to be (and is,
given current proposals) correct code, given the fact that
the author knows (for example, because he wrote it) that
the function throw_my_exception really does throw. The
question is whether your proposal would allow similar code
to compile cleanly without extra overhead in the source
code or at runtime. Idioms that are robust for a human
can be opaque to a compiler; conservative rules would
have to either add runtime cost or declare the idiom shown
above to be invalid, and either would be a shame.
(Howard's put a *lot* of time into considering the rvalue
reference proposals, and my first assumption if something
looks odd when I see his rvalue reference-enabled code is
to assume that I have something to learn.)
-- 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 ]
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Thu, 8 Mar 2007 13:09:48 CST Raw View
Howard Hinnant wrote:
1.
>
>> "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.
> 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.
>
> 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:
> A a1
> if (foo())
> {
> A @a2(a1);
> ...
> }
else
{
> // 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".
> // 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:
> int main()
> {
> A a1
"copy ctor" used, state "ctor"
> if (foo())
> {
> A @a2(a1);
"move ctor" used to create "a2"
"a1" must be "ctor" befor and became "dtor"
> ...
> }
else
{
> // 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:
> 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
> // 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 ]
Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Thu, 8 Mar 2007 23:42:31 GMT Raw View
In article <esojh4$9c6$1@aioe.org>, "Grizlyk" <grizlyk1@yandex.ru>
wrote:
> I can repeat again:
Sorry for making you repeat.
> 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".
> 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 ]
Author: tasjaevan@gmail.com
Date: Fri, 9 Mar 2007 09:02:44 CST Raw View
On Mar 8, 7:09 pm, "Grizlyk" <grizl...@yandex.ru> 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?
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Mon, 12 Mar 2007 17:00:29 GMT Raw View
tasjaevan@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?
--
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 ]
Author: jdennett@acm.org (James Dennett)
Date: Mon, 12 Mar 2007 17:22:57 GMT Raw View
Grizlyk wrote:
> tasjaevan@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.
-- 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 ]
Author: tasjaevan@gmail.com
Date: Mon, 12 Mar 2007 13:19:57 CST Raw View
On Mar 12, 5:22 pm, jdenn...@acm.org (James Dennett) wrote:
> 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'.
> -- 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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 13 Mar 2007 14:44:53 GMT Raw View
James Dennett 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.
Well, i have seen now, that the "couple" related to "times", not to
"auto_ptr(unique_ptr)".
> 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"
Can you give me examples of any other possible values of the expression
"auto_ptr(unique_ptr)" in the context: "in most _very_ important cases (as
for auto_ptr(unique_ptr))". I do not insist, it is just interesting why
"guess" is required here.
> but it's not clear to me which
> issue you are attempting to raise regarding those smart
> pointers.
What does "which issue you are attempting to raise" mean (what "issue" means
in the context of "raise")? Maybe "raise issue of auto_ptr(unique_ptr)"
means "speaking about problems of auto_ptr(unique_ptr) implementation"?
If "yes", i have written:
> It is very important because we will be able to make good
> reliable replacement of "garbage collector" _without_
> any overhead.
The "It" means "to do "compile time testing" for auto_ptr(unique_ptr)
implementation" here. Maybe i should write: "_This_ is very important
because..."?
--
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 ]
Author: tasjaevan@gmail.com
Date: Tue, 13 Mar 2007 10:55:51 CST Raw View
On Mar 13, 2:44 pm, grizl...@yandex.ru ("Grizlyk") wrote:
>
> Can you give me examples of any other possible values of the expression
> "auto_ptr(unique_ptr)" in the context: "in most _very_ important cases (as
> for auto_ptr(unique_ptr))". I do not insist, it is just interesting why
> "guess" is required here.
>
I read it as pseudo-C++. I thought you were talking about some kind of
conversion between the two types.
>
> > It is very important because we will be able to make good
> > reliable replacement of "garbage collector" _without_
> > any overhead.
>
I think we agree that fixing auto_ptr is an important goal of adding
move semantics to C++. Could you post a use case that unique_ptr does
not support (in your opinion)?
(Also, I should point out that unique_ptr has very little to do with
garbage collection. It is an important tool for achieving
*deterministic* destruction - almost the opposite of garbage
collection)
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Wed, 28 Feb 2007 18:13:36 GMT Raw View
Howard Hinnant wrote:
>
> 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 ]
Author: tasjaevan@gmail.com
Date: Thu, 1 Mar 2007 13:33:36 CST Raw View
On Feb 28, 6:13 pm, grizl...@yandex.ru ("Grizlyk") wrote:
>
> 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
>
> 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).
>
> 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.
> 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.
>
> 4. "Non-const" is not the same as "moveable".
> =============================================
>
In the rvalue reference proposal, moving is explicit (using
std::move), except from temporaries (rvalues).
>
> 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.
>
> 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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Sat, 3 Mar 2007 07:34:08 GMT Raw View
tasjaevan@gmail.com wrote:
>>
>> 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.
>>
>> 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.
>>
>> 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?
> 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:
> 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
> {
> 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&)".
> return std::move(d);
Probably you want to say
return 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.
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.
>> 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.
> 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:
>> 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
>>
>> }
>>
>> 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.
>>
>> 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?
>>
>> 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++.
> 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 ]
Author: "=?iso-8859-1?q?Pedro_Lamar=E3o?=" <pedro.lamarao@gmail.com>
Date: Sat, 3 Mar 2007 10:24:18 CST Raw View
On 3 mar, 04:34, grizl...@yandex.ru ("Grizlyk") wrote:
> 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 ]
Author: "Grizlyk" <grizlyk1@yandex.ru>
Date: Sun, 4 Mar 2007 09:56:52 CST Raw View
Pedro Lamar o wrote:
>
>> 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" :). 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 ]
Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Tue, 6 Mar 2007 17:52:55 GMT Raw View
In article <esdvnk$t8v$1@aioe.org>, "Grizlyk" <grizlyk1@yandex.ru>
wrote:
> "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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 20 Feb 2007 16:29:44 GMT Raw View
pongba@gmail.com wrote:
>>
>> 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.
In context of my message "moveable" is required property, I want to
implement moveable class, how to declare it? For example, for copyable i
must declare public copy ctor.
>> ---
>> 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.
I will try, but it is something wrong here - too many Nxxx to read to
understand how to do so trivial thing.
--
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 ]
Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Tue, 20 Feb 2007 20:50:31 GMT Raw View
In article <erdo82$mtu$1@aioe.org>, grizlyk1@yandex.ru ("Grizlyk")
wrote:
> > 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 ]
Author: pongba@gmail.com
Date: Wed, 14 Feb 2007 23:44:03 CST Raw View
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 ]
Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Sun, 18 Feb 2007 23:33:19 GMT Raw View
pongba@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.
---
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 ]
Author: pongba@gmail.com
Date: Mon, 19 Feb 2007 02:36:58 CST Raw View
On Feb 19, 7:33 am, grizl...@yandex.ru ("Grizlyk") wrote:
> 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.
>
> ---
> 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 ]