I just watched a presentation by Nicolai Josuttis “The Nightmare of Move Semantics for Trivial Classes”
In the presentation he shows how to build a "perfect customer class", so that it's constructor accepts up to all three arguments with as few mallocs as possible. Here are the solutions he presents:
// 11 mallocs (4cr + 7cp + 1mv)
Customer(std::string f = "", std::string l = "", int i = 0) :
first(f), last(l), id(i)
{}
// 5 mallocs (4cr + 1cp + 5mv)
Customer(std::string f = "", std::string l = "", int i = 0) :
first(std::move(f)), last(std::move(l)), id(i)
{}
// all manual combinations carefully avoiding ambiguities, such as
// 5 mallocs (4cr + 1cp + 1mv)
Customer(const std::string&, const std::string&, int i = 0);
// 5 mallocs (4cr + 1cp + 1mv)
template<typename S1, typename S2 = std::string, typename = std::enable_if<std::is_convertible_v<std::string>>
Customer(S1&& f, S2&& l = "", int i = 0):
first(std::forward<S1>(f)), last(std::forward<S1>(l)), id(i)
{}
In cases like this I use an idiom (shown below), that he didn't consider in the presentation, nor did I find it elsewhere, yet I think it is suitable in both terms of performance and usage. It uses private inheritance of a struct, that has the members. The constructor template uses a parameter pack to do the job. So I wonder: is there anything wrong with this approach? Should I expect some problems in performance or usage? Any other pitfalls? Is this a known idiom that I just missed? (But why it wasn't there?)
Here is the code for the class:
#include <string>
#include <utility>
struct CustomerData
{
std::string first;
std::string last;
int id;
};
class Customer: private CustomerData
{
public:
// Constructor template
template<typename... Args>
Customer(Args... args):
CustomerData{std::move(args)...}
{
}
};
Edit: 1) POD changed to struct (POD containing string is not a POD, thanks to a remark by Daniel Langr), 2) added an explanatory sentence if one doesn't want to watch the whole video
Edit 2: std::forward changed to std::move, thanks to remark of Jarod42
Edit 3: added reference code on request of apple apple