jeudi 27 septembre 2018

Detect rvalues in forwarding references

I'm trying to write a type-safe, forwarding reference enabled version of list append.

#include <list>
using namespace std;

// Both l1, l2 are mutable, l2 will be copied if lvalue
template<typename L1, typename L2,
         typename T = typename std::remove_reference_t<L1>::value_type,
         typename = std::enable_if_t<is_same_kind_v<L1, list<T>>>,
         typename = std::enable_if_t<is_same_kind_v<L2, list<T>>>>
inline static list<T> app(L1&& l1, L2&& l2) noexcept {
    if constexpr (std::is_rvalue_reference_v<L2>) {
        l1.splice(l1.end(), l2);
        std::cout << "Is RVALUE" << std::endl;
    } else {
        l1.insert(l1.end(), FWD(l2.begin()), FWD(l2.end()));
        std::cout << "Is LVALUE" << std::endl;
    }
    return l1;
}

I'm trying to save as many list copies as possible. I only want one function definition (instead of three for list<T>&, const list<T>&, list<T>&&). The idea is that lvalues should not be modified (insert does not change l2) while rvalues are temporary and can thus be modified (splice moves from l2 to l1).

However when I call my app function like this (my own print function for std::list<T>).

 print(app(lval, list<int>{1,3,5}));

Is LVALUE!!!

[2, 4, 6, 8, 1, 3, 5]

Aucun commentaire:

Enregistrer un commentaire