Simplifying C++11 optimal parameter passing when a copy is needed
- by Mr.C64
It seems to me that in C++11 lots of attention was made to simplify returning values from functions and methods, i.e.: with move semantics it's possible to simply return heavy-to-copy but cheap-to-move values (while in C++98/03 the general guideline was to use output parameters via non-const references or pointers), e.g.:
// C++11 style
vector<string> MakeAVeryBigStringList();
// C++98/03 style
void MakeAVeryBigStringList(vector<string>& result);
On the other side, it seems to me that more work should be done on input parameter passing, in particular when a copy of an input parameter is needed, e.g. in constructors and setters.
My understanding is that the best technique in this case is to use templates and std::forward<>, e.g. (following the pattern of this answer on C++11 optimal parameter passing):
class Person
{
std::string m_name;
public:
template <class T,
class = typename std::enable_if
<
std::is_constructible<std::string, T>::value
>::type>
explicit Person(T&& name)
: m_name(std::forward<T>(name))
{
}
...
};
A similar code could be written for setters.
Frankly, this code seems boilerplate and complex, and doesn't scale up well when there are more parameters (e.g. if a surname attribute is added to the above class).
Would it be possible to add a new feature to C++11 to simplify code like this (just like lambdas simplify C++98/03 code with functors in several cases)?
I was thinking of a syntax with some special character, like @ (since introducing a &&& in addition to && would be too much typing :)
e.g.:
class Person
{
std::string m_name;
public:
/*
Simplified syntax to produce boilerplate code like this:
template <class T,
class = typename std::enable_if
<
std::is_constructible<std::string, T>::value
>::type>
*/
explicit Person(std::string@ name)
: m_name(name) // implicit std::forward as well
{
}
...
};
This would be very convenient also for more complex cases involving more parameters, e.g.
Person(std::string@ name, std::string@ surname)
: m_name(name),
m_surname(surname)
{
}
Would it be possible to add a simplified convenient syntax like this in C++?
What would be the downsides of such a syntax?