Сравните два кортежа, но только первые два аргумента - PullRequest
0 голосов
/ 30 января 2019

У меня есть std::tuple например

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

, и я хочу сравнить со вторым кортежем, но только с первыми двумя аргументами.Примерно так:

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

Если я делаю это таким образом, я получаю следующую ошибку:

error C2338: cannot compare tuples of different sizes

Как я могу это сделать?

РЕДАКТИРОВАТЬ1:

Оба кортежа имеют одинаковый размер.Я видел, как два сравниваются по EQUALITY с std::tie(), но было бы лучше, я мог бы написать:

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

EDIT2:

И что, если я хочу это:

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

Ответы [ 2 ]

0 голосов
/ 30 января 2019

А что, если я хочу это:

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

Итак, вы хотите сравнить поднаборы с некоторыми элементами оригинальных кортежей?Не обязательно первые два элемента?

Как насчет функции, которая, если объект кортежа содержит список индексов с переменным индексом, возвращает соответствующий поднабор кортежа?

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

Так что вы можете написать

   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;
0 голосов
/ 30 января 2019

В вашем примере вы сравниваете кортеж размера 3 (std::tie(k, p, std::ignore)) с кортежем размера 1 (std::tie(key), который имеет тип std::tuple<std::tuple<uint16_t, uint16_t, uint32_t>>).Вы не должны вызывать tie для кортежа, потому что он создаст кортеж с одним элементом.

Следующий код также не работает с GCC 8.2.1, поскольку компилятор не знает, как обрабатыватьstd::ignore сравнение с uint32_t.В этом случае я бы написал специализированную функцию сравнения для этого типа (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;
}
...