lundi 23 octobre 2017

Is there a way to convert a list of lvalues and rvalues to a tuple with reference types and full types respectively?

So given the following 2 functions:

int rvalue();
int& lvalue();

The following would be valid:

std::tuple<int, int&> x = appropriate_fn(lvalue(), rvalue());

I was thinking something like it like this:

template <typename T, typename...Ts>
auto make_comparible(T const& arg, Ts&&...args)
{
    return std::make_tuple(T(arg), make_comparible(args...));
}

template <typename T, typename...Ts>
auto make_comparible(T& arg, Ts&&...args)
{
    return std::make_tuple<T&>(arg, make_comparible(args...));
}

template <typename T>
auto make_comparible(T const& arg)
{
    return std::tuple<T>(T(arg));
}

template <typename T>
auto make_comparible(T& arg)
{
    return std::tuple<T&>(arg);
}

But there's three issues this that I can see.

  1. This is not a simple std::tuple, but a nested one. Which, come to think about it, may not be an issue as I just want to do comparisons (less than, equal to) on it and should still work.

  2. This doesn't distinguish between a temporary and a const reference. This is a bit annoying but I don't see any way around it.

  3. Most importantly, it doesn't work. Given the following:

    std::tuple<int, std::tuple<int&>> x = make_comparible(rvalue(), lvalue());
    std::tuple<int&, std::tuple<int>> y = make_comparible(lvalue(), rvalue());
    
    

    The first one is works, but the second one give an error because make_comparible() is returning std::tuple<int, std::tuple<int&>> instead of std::tuple<int&, std::tuple<int>>. Demo

So, is what I'm asking for possible, or is it a pipe dream?

The use case is that I want to define a function in a class that will return a tuple (or otherwise comparable type), which will not result in a dangling pointer/reference, and which will be easy to use.

Aucun commentaire:

Enregistrer un commentaire