Consider two implementations of a class:
struct S1
{
    std::vector< T > v;
    void push(T && x) { v.push_back(std::move(x)); }
    void push(T const & x) { push(T(x)); }
    void pop() { v.pop_back(); }
    void replace(T && x) { pop(); push(std::move(x)); }
    void replace(T const & x) { replace(T(x)); }
};
struct S2
{
    std::vector< T > v;
    void push(T x) { v.push_back(std::move(x)); }
    void pop() { v.pop_back(); }
    void replace(T x) { pop(); push(std::move(x)); }
};
S1's push overloads express exactly what I want. S2's push is a way to express it in a less verbose way.
But I worry that there is a drawback connected with the excessive move-construction of objects.
Can modern compilers reduce the expression std::move(T(std::move(t))) to std::move(t) for some t where decltype(t) is T&? Can modern compilers optimize out unnecessary moves? Or is this prohibited by the standard?
 
     
    