I'm working on a simple wrapper template class that logs when special member functions are called. These functions cannot be defaulted since they perform additional logging related tasks.
template <typename T>
struct logger {
logger(T const& value) : value_(value) { /*...log...*/ }
logger(T&& value) : value_(std::move(value)) { /*...log...*/ }
logger(logger const& other) : value_(other.value_) { /*...log...*/ }
logger(logger&& other) : value_(std::move(other.value_)) { /*...log...*/ }
T value_;
};
Unfortunately, when the wrapped type is an rvalue-reference the copy-constructor fails to compile with the following error message:
error: cannot bind ‘int’ lvalue to ‘int&&’
The reason is that an implicit copy constructor will behave somewhat different for an rvalue-reference member:
[class.copy 12.8/15] The implicitly-defined copy/move constructor for a non-union class
Xperforms a memberwise copy/move of its bases and members. [...] Letxbe either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter. Each base or non-static data member is copied/moved in the manner appropriate to its type:
- if the member is an array, each element is direct-initialized with the corresponding subobject of
x;- if a member m has rvalue reference type
T&&, it is direct-initialized withstatic_cast<T&&>(x.m);- otherwise, the base or member is direct-initialized with the corresponding base or member of
x.
Which brings me to my question: how does one write a generic copy-constructor that behaves as an implicitly defined copy-constructor, even when working with rvalue-references as members.
For this particular case, I could add an additional specialization for rvalue-references. However, I'm looking for a generic solution that doesn't restrict to single members and does not introduce code duplication.
logger(logger const& other) : value_(static_cast<T>(other.value_))? sinceTisint&&- KalTisint&&for only one particular case, it could be a huge object in another and that would create an unnecessary copy. - K-balloTis an rvalue reference? You don't have value semantics in this case. The move ctor should probably be disabled for this case, too, to avoid lifetime issues. - dyp