Date: Wed, 22 Jan 2020 21:13:11 +0100
Hello
I think this paper go to far, instead of changing result of move
operation we should only add requirement that standard algorithms only
can touch move-out object by assigned or deletion, any other operation
is not allowed. This will cause that implementation of `IndirectInt`
show in paper will be correct handled by any of std algorithm.
Reason is simple "partially formed state" is another of case of "Valid
but unspecified state" of object. In this type `<=>` have precondition
that object is not moved-out state.
This mean library should assume minimal thing about user types.
Another problem is that `IndirectInt` is incorrect in because it try
use types that have "incompatible" invariants to final type. By
definition `std::shared_ptr` have `nullptr` semantic after move, this
is contradiction to desired behavior.
Showed solution to this problem using `i_.swap(rhs.i_);` is incorrect
because it require lot of boiler plate code and is very easy to get
wrong.
I think correct fix for this problem should be by "fixing" core
problem of `std::shared_ptr`:
```
//new helper class that you need write only once
template<typename T>
struct skip_move
{
T value;
skip_move(T i): value(std::move(i)) {}
skip_move(skip_move&& rhs) : value(rhs.value) { }
skip_move& operator=(skip_move&& rhs) { value.swap(rhs.value); }
skip_move(const skip_move&) = default;
skip_move& operator=(const skip_move&) = default;
//probaby many other member functions
}
class IndirectInt
{
skip_move<std::shared_ptr<const int>> i_;
skip_move<std::shared_ptr<const int>> j_; //we do not need update
all function to handle it
public:
IndirectInt(int i): i_{std::make_shared<const int>(i)} {}
friend auto operator<=>(const IndirectInt& lhs, const IndirectInt& rhs)
{
return *lhs.i_.value <=> *rhs.i_.value;
}
}
```
This could be used for other types too that have some special meaning.
We could too add other helper types like `clear_move` that will tewak
other type behaviors
to fit our needs.
I think this paper go to far, instead of changing result of move
operation we should only add requirement that standard algorithms only
can touch move-out object by assigned or deletion, any other operation
is not allowed. This will cause that implementation of `IndirectInt`
show in paper will be correct handled by any of std algorithm.
Reason is simple "partially formed state" is another of case of "Valid
but unspecified state" of object. In this type `<=>` have precondition
that object is not moved-out state.
This mean library should assume minimal thing about user types.
Another problem is that `IndirectInt` is incorrect in because it try
use types that have "incompatible" invariants to final type. By
definition `std::shared_ptr` have `nullptr` semantic after move, this
is contradiction to desired behavior.
Showed solution to this problem using `i_.swap(rhs.i_);` is incorrect
because it require lot of boiler plate code and is very easy to get
wrong.
I think correct fix for this problem should be by "fixing" core
problem of `std::shared_ptr`:
```
//new helper class that you need write only once
template<typename T>
struct skip_move
{
T value;
skip_move(T i): value(std::move(i)) {}
skip_move(skip_move&& rhs) : value(rhs.value) { }
skip_move& operator=(skip_move&& rhs) { value.swap(rhs.value); }
skip_move(const skip_move&) = default;
skip_move& operator=(const skip_move&) = default;
//probaby many other member functions
}
class IndirectInt
{
skip_move<std::shared_ptr<const int>> i_;
skip_move<std::shared_ptr<const int>> j_; //we do not need update
all function to handle it
public:
IndirectInt(int i): i_{std::make_shared<const int>(i)} {}
friend auto operator<=>(const IndirectInt& lhs, const IndirectInt& rhs)
{
return *lhs.i_.value <=> *rhs.i_.value;
}
}
```
This could be used for other types too that have some special meaning.
We could too add other helper types like `clear_move` that will tewak
other type behaviors
to fit our needs.
Received on 2020-01-22 14:15:55