Simplifying C++11 optimal parameter passing when a copy is needed

Posted by Mr.C64 on Programmers See other posts from Programmers or by Mr.C64
Published on 2012-10-30T18:00:09Z Indexed on 2012/10/30 23:19 UTC
Read the original article Hit count: 277

Filed under:
|
|

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?

© Programmers or respective owner

Related posts about c++

Related posts about language-design