fre*_*low 6 c++ templates rvalue-reference move-semantics perfect-forwarding
我有以下两个函数模板重载:
template<typename T>
optional<T> some(const T& x)
{
return optional<T>(x);
}
template<typename T>
typename std::enable_if<std::is_rvalue_reference<T&&>::value, optional<T> >::type
some(T&& x)
{
return optional<T>(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)
我通过完美转发统一过载的第一次尝试失败了:
template<typename T>
optional<T> some(T&& x)
{
return optional<T>(std::forward<T>(x));
}
error: forming pointer to reference type 'const std::basic_string<char>&'
Run Code Online (Sandbox Code Playgroud)
和我的第二次尝试一样:
template<typename T>
optional<typename std::remove_reference<T>::type> some(T&& x)
{
return optional<typename std::remove_reference<T>::type>(std::forward<T>(x));
}
error: no matching function for call to
'std::basic_string<char>::basic_string(gpa::optional<const std::basic_string<char> >)'
Run Code Online (Sandbox Code Playgroud)
是否有一种简洁的方法来统一过载,或者我应该忍受它们?
一般来说,最好的方法是按值获取对象并让调用者决定是复制还是移动它:
template<typename T>
optional<T> some(T x)
{
return optional<T>(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)
如果调用者使用临时值调用它或使用std::move它们的值,那么它就会被移动。否则就被复制了。
是的,这确实意味着您将进行一次额外的移动(如果移动与复制相同,则意味着进行两次复制)。如果这对您来说是一个重大的性能问题,那么您将不得不使用两个重载实现。