I want to write a template which can turn lvalue/rvalue to rvalue using universal reference like std::forward For rvalue, just forward it. For lvalue, copy it.
it is used as below
template<typename T>
void func(T&& arg) {
f_take_rv(make_rv<T>(arg)); // f_take_rv takes right value only
}
Here is my implement
template<typename T> // for lvalue
constexpr T make_rv(typename std::remove_reference<T>::type& arg) {
return arg;
}
template<typename T> // for rvalue
constexpr T&& make_rv(typename std::remove_reference<T>::type&& arg) {
return static_cast<T&&>(arg);
}
However, it always goes to the lvalue one
I also tried std::enable_if to control its type deduction.
template<typename T>
constexpr typename std::enable_if<
std::is_reference<T>::value,
typename std::remove_reference<T>::type
>::type make_rv(typename std::remove_reference<T>::type& arg) { return arg; }
template<typename T>
constexpr typename std::enable_if<
!std::is_reference<T>::value,
T
>::type&& make_rv(typename std::remove_reference<T>::type&& arg) {
return static_cast<T&&>(arg);
}
But it failed for literal string, like "str": no matching function for call to 'make_rv<const char(&)[4]>(const char [4])'
Could you tell me how to implement it
gcc implement of std::forward for reference:
template<typename _Tp> // forwarding an lvalue
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept {
return static_cast<_Tp&&>(__t);
}
template<typename _Tp> // forwarding an rvalue
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept {
return static_cast<_Tp&&>(__t);
}
Aucun commentaire:
Enregistrer un commentaire