【问题标题】:How to compare tuples of different length?如何比较不同长度的元组?
【发布时间】:2016-02-22 20:30:40
【问题描述】:

我想写一个比较器来比较不同长度但具有相同“前缀”的元组。考虑以下情况,我有两个元组。

auto t1 = std::make_tuple(10, "Test1");
auto t2 = std::make_tuple(10, "Test", 3.14);


我想对 t1

【问题讨论】:

  • 是什么阻止你这样做?向我们展示一些努力 :) 提示:考虑递归。
  • 听起来很学术。如果您有元组 A、B 和 A、C,其中 A 相同,而 B 和 C 属于不同(不可比较的)类型,该怎么办?
  • @SergeyA,实际上,我根本不知道如何处理它 :)
  • @DieterLücking,好问题,在这种情况下,我猜应该发出编译时错误

标签: c++ c++11 tuples stdtuple


【解决方案1】:

好吧,既然没有人插话,这就是解决方案。它使用C++14 std::index_sequence,所以递归隐藏在其中。

#include <tuple>
#include <utility>

template<class... ARGS1, class... ARGS2, std::size_t... Is>
bool tuple_compare_helper(const std::tuple<ARGS1...>& lhs, const std::tuple<ARGS2...>& rhs, std::index_sequence<Is...> ) {
  return std::tie(std::get<Is>(lhs)...) < std::tie(std::get<Is>(rhs)...);

}

template<class... ARGS1, class... ARGS2> 
bool tuple_compare(const std::tuple<ARGS1...>& lhs, const std::tuple<ARGS2...>& rhs) {
  const auto min_size = std::min(sizeof...(ARGS1), sizeof...(ARGS2));

  return tuple_compare_helper(lhs, rhs, std::make_index_sequence<min_size>());
}

// test driver
#include <iostream>
int main() {
  auto t1 = std::make_tuple(1, std::string("One"), 2.0);
  auto t2 = std::make_tuple(3, std::string("Two"));


  std::cout << tuple_compare(t2, t1) << "\n";
}

【讨论】:

  • std::make_tuple 将...创建一个新的副本元组来比较相应的元素,这不是最有效的方法。考虑为此使用std::tie
  • @PiotrSkotnicki,正是我的想法:) 将编辑和替换。
  • 好的,很有趣的技术,但是,我不明白调用 std::get(lhs)... 时会生成什么代码?你能详细说明一下吗?无论如何这是正确的答案
  • std::min 现在是constexpr,所以min_size 的表达式可以简化一点。
  • @kreuzerkrieg,这称为 pack 扩展en.cppreference.com/w/cpp/language/…。基本上,它将被替换为(std::get&lt;0&gt;(lhs), std::get&lt;1&gt;(lhs&gt;, ..., std::get&lt;N&gt;(lhs)),其中 N 是 Is 中的最后一个索引。
【解决方案2】:

t1 和 t2 是完全不同的类型,所以你不能比较它们。 (元组是模板类型;它们在运行时不是多态的) 我认为唯一的 t-way 是一个临时元组,它需要 t2 first 和 seconds 元素进行比较

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多