Why does std::forward return static_cast and not static_cast?

Let’s have a function called Y that overloads:

void Y(int& lvalue)
{ cout << "lvalue!" << endl; }

void Y(int&& rvalue)
{ cout << "rvalue!" << endl; }

Now, let's define a template function that acts like std::forward

template
void f(T&& x)
{
   Y( static_cast(x) );   // Using static_cast(x) like in std::forward
}

Now look at the main()

int main()
{
   int i = 10;

   f(i);       // lvalue >> T = int&
   f(10);      // rvalue >> T = int&&
}

As expected, the output is

lvalue!
rvalue!

Now come back to the template function f() and replace static_cast(x) with static_cast(x). Let's see the output:

lvalue!
rvalue!

It's the same! Why? If they are the same, then why std::forward<> returns a cast from x to T&&?

Refactoring with C++ 11

Given the new toolset provided by c++ lots of programmers, aiming at code simplification, expressiveness, efficiency, skim through their old code and make tweaks (some pointless, some successful) to achieve their goals. Whilst trying not to loose too much time on such labors and just make non intrusive and self contained changes, what are the best practices?

Let me cross out the obvious :

  • Use auto to run iterator based loops :

    for (std::vector::const_iterator it(lala.begin()), ite(lala.end()); it != ite;     
    ++it);
    // becomes
    for (auto it(lala.cbegin()), ite(lala.cend()); it != ite; ++it);
    
  • Use tie for multiple assignments that just produce C-style rows of code ( how to assign multiple values into a struct at once? )

    a = 1;
    b = 2; 
    c = 3;
    d = 4; 
    e = 5;
    // becomes
    std::tie(a, b, c, d, e) = std::make_tuple(1, 2, 3, 4, 5);
    
  • To make a class non inheritable just declare it as “final” and delete the code that achieved such a behavior http://www.parashift.com/c++-faq/final-classes.html

  • Use the delete keyword to explicitly hide constructors/destructors instead of declaring them private (eg code to create heap based objects, non copyable objects etc)

  • Turn trivial functors created just to facillitate the execution of a single STL algorithm into lambda functions (apart from reducing code cluttering you’ll have guaranteed inlined calls)

  • Simplify RAII wrapping of an object by just using a smart pointer

  • Get rid of bind1st, bind2nd and just use bind

  • Replace hand written code for type traits (Is_ptr_but_dont_call_for_const_ptrs<> and such 🙂 ) with standard code provided by < type_traits >

  • Stop including boost headers for functionallity now implented in STL (BOOST_STATIC_ASSERT vs static_assert)

  • Provide move semantics to classes (although this wouldn’t qualify as a dirty/quick/easy change)

  • Use nullptr where possible instead of the NULL macro and get rid of the code that filled containers of pointers with 0’s casted to object type

    std::vector f(23);
    for (std::size_t i(0); i < 23; ++i)
    { f[i] = static_cast(0); }
    // becomes
    std::vector f(23, nullptr);
    
  • Clear the vector data accessing syntax

    std::vector vec;
    &vec[0];    // access data as a C-style array
    vec.data(); // new way of saying the above
    
  • Replace throw() with noexcept (apart from avoiding the deprecated exception specifiation you get some speed benefits http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler @ 00.29.42)

    void some_func() noexcept; // more  optimization options
    void some_func() throw();  // fewer optimization options
    void some_func() ;         // fewer optimization options
    
  • Replace code where you’d push a tempory in a container and hoped that the optimizer would ellide the copy away, with an “emplace” function where available, in order to perfectly forward the argument and construct directly an object into a container without temporary at all.

    vecOfPoints.push_back(Point(x,y,z)); // so '03
    vecOfPoints.emplace_back(x, y, z);   // no copy or move operations performed
    

UPDATE

The answer by Shafik Yaghmour was rightfully awarded the bounty for having the greatest acceptance by the audience.

The answer by R Sahu was my accepted one, because the combination of features it proposes captures the spirit of refactoring : making code clearer and cleaner and simpler and elegant.