0

I know std::move A const Object will actually invoke T's copy constructor, So I want to do some Experiments of implementation of my move and inner of this remove to remove const such like :

template<typename _Tp>
typename std::remove_const<typename std::remove_reference<_Tp>::type>::type&&
my_move(_Tp&& __t) noexcept {
    using removed_reference = typename std::remove_reference<_Tp>::type;
    using removed_ref_const = typename std::remove_const<removed_reference>::type;
    return static_cast<removed_ref_const&&>(__t);
}

but This code will not compile? Why

And If I change the order of remove_reference and remove_const, This code will compile but not as my expect, my_move(const Object T) still uses Object T's copy constructor?

And Also who can give me a right implementation which will show when I remove const, This will use T's move constructor.

T may be as:

struct T
{
    T() = default;
    T(const T&) { std::cout << "copy ctor\n"; }
    T(T&&)      { std::cout << "move ctor\n"; }
};

int main() {
    const T t;
    T a = my_move(t);
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
bryantism
  • 167
  • 9
  • 2
    Ok I didn't read this in detail, but if your code modifies the state of `t`, then it is wrong, as `t` is const. – Neil Kirk Aug 09 '14 at 12:18
  • 1
    Please let us know what made you think that attempting this is safe at all. A `move` will modify the non-const source. That's the whole point of it. If that source can be modified, it shouldn't be const in the first place. Please amend your question with a description of what higher-level problem you're trying to solve. Perhaps that underlying issue has a better solution than what you propose here. – Kuba hasn't forgotten Monica Aug 09 '14 at 12:43

1 Answers1

2

To remove the constness of an object, the cast to use is const_cast and not static_cast

Do you want something like :

template<typename T>
T&& my_move(const T& t) noexcept {
    return std::move(const_cast<T&>(t));
}

(with the possible problems to remove const from object)...

Live example

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • This is a straightforward way, but how to do this in the inner implementation of move ? – bryantism Aug 09 '14 at 12:25
  • By changing your `static_cast` by `const_cast` your code compile... but using `const_cast` this way may lead to UB. – Jarod42 Aug 09 '14 at 12:35
  • I found here remove_const only can remove top level const, since t passed to my_move is a lvalue, It's resolved as rvalue reference, so may be remove_const can't remove the const? – bryantism Aug 09 '14 at 12:42
  • `remove_const` remove `const` for the *type* not the **value**, so in your version you have `static_cast(t)` where `t` is `const T&`. – Jarod42 Aug 09 '14 at 12:49
  • 1
    and why use const_cast may lead to Undefined Behavior? – bryantism Aug 09 '14 at 13:06
  • @bryantism: you may look at [is-const-cast-safe](http://stackoverflow.com/questions/357600/is-const-cast-safe) – Jarod42 Aug 09 '14 at 13:22