2

I have a std::tuple e.g.

std::tuple<uint16_t, uint16_t, uint32_t> key{};
std::tuple<uint16_t, uint16_t, uint32_t> key2{};
const auto [k, p, r] = key;

and I want to compare with a second tuple but only the first two args. Something like that:

if(std::tie(k, p, std::ignore) < std::tie(key)) { ... }

If I do it in the this way, I get the following error:

error C2338: cannot compare tuples of different sizes

How can I do that?

EDIT1:

Both tuple have the same size. I seen how two compare on EQUAlITY with std::tie() but it would be nicer I could write:

if(std::tie(k, p, std::ignore) == std::tie(key)) { ... }

EDIT2:

Also what if I want this:

if(std::tie(k, std::ignore, p) == std::tie(key)) { ... }
max66
  • 65,235
  • 10
  • 71
  • 111
makurisan
  • 467
  • 3
  • 13

2 Answers2

2

Also what if I want this:

if(std::tie(k, std::ignore, p) == std::tie(key)) { ... }

So you want compare sub-tuples with some elements of original tuples? Not necessarily the first two elements?

What about a function that, given a tuple object an template variadic index list, return the corresponding sub-tuple?

template <std::size_t ... Is, typename T>
auto getSubTuple (T const & t)
 { return std::tie(std::get<Is>(t)...); }

So you can write

   std::tuple<std::uint16_t, std::uint16_t, std::uint32_t> key{0, 1, 2};
   std::tuple<std::uint16_t, std::uint16_t, std::uint32_t> key2{0, 3, 2};
    
   std::cout << (getSubTuple<0u, 2u>(key) == getSubTuple<0u, 2u>(key2)) << std::endl;
Community
  • 1
  • 1
max66
  • 65,235
  • 10
  • 71
  • 111
0

In your example, you are comparing a tuple of size 3 (std::tie(k, p, std::ignore)) with a tuple of size 1 (std::tie(key), which has the type std::tuple<std::tuple<uint16_t, uint16_t, uint32_t>>). You shouldn't call tie on a tuple, because it will create a tuple with a single item in it.

The following code also fail with GCC 8.2.1 because the compiler doesn't know how to handle the std::ignore comparison with an uint32_t. In this case I would write a specialized compare function for this type (std::tuple<std::tuple<uint16_t, uint16_t, uint32_t>>).

#include<tuple>

int main() {
    uint16_t k = 0;
    uint16_t p = 0;
    std::tuple<uint16_t, uint16_t, uint32_t> key{};
    if(std::tie(k, p, std::ignore) < key) {
        // TODO
    }
    return 0;
}
bolov
  • 72,283
  • 15
  • 145
  • 224
Simon Doppler
  • 1,918
  • 8
  • 26
  • You're correct an I should have said a custom comparison function (not operator). – Simon Doppler Jan 30 '19 at 13:24
  • I don't know if I am fond of the compare function. I personally prefer the sub-tuple approach, but your ideea is a valid option that might make sense in certain scenarios. However in the current state your post is barely an answer. You can improve it by showing an implementation of the function. – bolov Jan 30 '19 at 13:30
  • Simon Doppler: That was you said that I compare a tuple of different size was an example to solve the problem. The reason why I come here was that I want to compare tuples with the same size but ignore args. – makurisan Jan 30 '19 at 13:37