Universal reference in a class template
Your solution is principally correct. If you want to play nice with potential generic traits (at the cost of a potentially uglier error message), you'd replace the static_assert with SFINAE:

template &lt;
    class UR = T,
    class TypeMustBeT = std::enable_if_t&lt;std::is_same&lt;std::remove_reference_t&lt;UR&gt;, T&gt;::value&gt;
&gt;
void Add(UR&amp;&amp; object)
{
    m_Vector.push_back(std::forward&lt;UR&gt;(object));
}


This way, the function Add will not exist at all when UR is not a forwarding reference for T1.

If you don't like the "template magic" involved in this and/or the compiler errors generated from misuse, you can solve this by providing the two strongly-typed overloads as std does and forward to a common private implementation:

void Add(const T&amp; object)
{
  AddImpl(object);
}

void Add(T&amp;&amp; object)
{
  AddImpl(std::move(object));
}

private:
template &lt;class UR&gt;
void AddImpl(UR&amp;&amp; object)
{
    static_assert(std::is_same&lt;std::remove_cv_t&lt;std::remove_reference_t&lt;UR&gt;&gt;, T&gt;::value, "UR and T should be the same!");
    m_Vector.push_back(std::forward&lt;UR&gt;(object));
}


This way, you can keep the static_assert-using version and keep the static assertion just to check your code's correctness, not the client code's.

Note that the static_assert needs to do std::remove_cv after std::remove_reference, otherwise it will fail for UR = const T&amp;. The same applies to the original code in the question too.

Unrelated to the question at hand, but I assume using namespace std; is for this reduced example only and is not present in your real code. It's very bad practice to put that into header files in real code.



1 Note that "forwarding reference" is the preferred term instead of "universal reference," since it captures the semantics better.