I am coding a small numeric analysis library in C++. I have been trying to implement using the latest C++11 features including move semantics. I understand the discussion and to
To build on what others have said:
std::move
in T::operator+( T const & )
is unnecessary and could prevent RVO.operator+
that delegates to T::operator+=( T const & )
.I'd also like to add that perfect forwarding can be used to reduce the number of non-member operator+
overloads required:
template< typename L, typename R >
typename std::enable_if<
std::is_convertible< L, T >::value &&
std::is_convertible< R, T >::value,
T >::type operator+( L && l, R && r )
{
T result( std::forward< L >( l ) );
result += r;
return result;
}
For some operators this "universal" version would be sufficient, but since addition is typically commutative we'd probably like to detect when the right-hand operand is an rvalue and modify it rather than moving/copying the left-hand operand. That requires one version for right-hand operands that are lvalues:
template< typename L, typename R >
typename std::enable_if<
std::is_convertible< L, T >::value &&
std::is_convertible< R, T >::value &&
std::is_lvalue_reference< R&& >::value,
T >::type operator+( L && l, R && r )
{
T result( std::forward< L >( l ) );
result += r;
return result;
}
And another for right-hand operands that are rvalues:
template< typename L, typename R >
typename std::enable_if<
std::is_convertible< L, T >::value &&
std::is_convertible< R, T >::value &&
std::is_rvalue_reference< R&& >::value,
T >::type operator+( L && l, R && r )
{
T result( std::move( r ) );
result += l;
return result;
}
Finally, you may also be interested in a technique proposed by Boris Kolpackov and Sumant Tambe as well as Scott Meyers' response to the idea.