template or member function selection
The constructor template's parameter is declared as forwarding reference. When being passed an lvalue such as line
, the template parameter X
is deduced as std::string&
, and after reference collapsing the parameter type is std::string&
, i.e. an lvalue-reference to non-const std::string
. It's an exact match and wins in overload resolution.
On the other hand, the constructor taking const std::string&
requires const-qualifying the argument, and the constructor taking std::string&&
can't be used with lvalues.