 <p><strong>Option 1:</strong></p> <pre><code>class Example { public: Example( std::string str, const std::complex&lt;float&gt;&amp; v ): m_str( std::move(str) ), m_v( v ) { } /* other methods */ private: std::string m_str; std::complex&lt;float&gt; m_v; }; </code></pre> <p>This has pretty good performance and is easy to code. The one place it falls a little short of the optimum is when you bind an lvalue to <code>str</code>. In this case you execute both a copy construction and a move construction. The optimum is only a copy construction. Note though that a move construction for a <code>std::string</code> should be very fast. So I would start with this.</p> <p>However if you really need to pull the last cycles out of this for performance you can do:</p> <p><strong>Option 2:</strong></p> <pre><code>class Example { public: Example( const std::string&amp; str, const std::complex&lt;float&gt;&amp; v ): m_str( str ), m_v( v ) { } Example( std::string&amp;&amp; str, const std::complex&lt;float&gt;&amp; v ): m_str( std::move(str) ), m_v( v ) { } /* other methods */ private: std::string m_str; std::complex&lt;float&gt; m_v; }; </code></pre> <p>The main disadvantage of this option is having to overload/replicate the constructor logic. Indeed this formula will become unrealistic if you have more than one or two parameters that you need to overload between <code>const&amp;</code> and <code>&amp;&amp;</code>.</p>