mardi 4 juillet 2023

How to implement a make_rv function in c

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