Why does std::forward converts lvalue and rvalue to rvalue reference?

Viewed 1303

I suppose I am confused with std::forward. My function which uses std::forward is following, but it is much simplified and modified to make explanation easily.

// This is an example code to explain my question simply.
template <typename Element>
void add(Element&& element) {
    static std::vector vec;
    vec.push_back(std::forward<Element>(element));
}

I tried two case with the function above; Case 1 lvalue argument and Case 2 rvalue argument.

Case 1: lvalue argument

auto some_class = SomeClass();
add(some_class);

Case 2: rvalue argument

add(SomeClass());

In debugger both cases passes the same following parts, std::forward part and std::vector part.

std::forward part:

template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }

std::vector part:

#if __cplusplus >= 201103L
  void
  push_back(value_type&& __x)
  { emplace_back(std::move(__x)); }

It seems std::forward part converts both cases to rvalue reference, &&, because it uses static_cast<_Tp&&>. And std::vector is treated both elements as rvalue reference because it uses std::move().

I have expected augment of Case 1 is lvalue because it has its own name and Case 2 is rvalue because it does not have its own name. I also have expected std::forward converts Case 1 to lvalue reference and Case 2 to rvalue reference. Are my understandings of lvalue, rvalue and std::forward correct? If so, why std::forward converts both as rvalue reference, &&.

If I made a mistake, I am sorry for taking your time.

2 Answers
Related