【问题标题】:Index sequence adding arrays together将数组加在一起的索引序列
【发布时间】:2021-01-16 15:39:23
【问题描述】:

我一直在尝试使用std::index_sequence,我一直在尝试让这段代码发挥任何帮助或指示作用?

template <typename tty,
          std::size_t ssz,
          typename is = std::make_index_sequence<std::min(sz, ssz)>>    
auto operator + (ss::array_helper<tty, ssz> right) const
{
    auto ret = *this;

    [ = ] ( auto s ) {
        [] ( ty& l , tty& r ) { l += r; } 
            ( ret [ is ] , right [ is ] )...;
    } ( is { } );

    return ret;
};

【问题讨论】:

  • 这里的sz 是什么?
  • ty 是当前数组的类型,sz 是当前数组的大小,tty 是运算符右侧的数组类型,ssz 是运算符右侧数组的大小。我试图只将每个索引与 std::index_sequence 一起添加,但只允许将最小大小添加在一起。
  • 你能不能edit你的问题显示minimal reproducible example? C++ 语法相当复杂。大多数愿意回答和帮助你的人都想仔细检查他们的答案是否真的可以编译和工作。如图所示,这几乎是不可能的,因为显示的代码使用了未定义的类型和命名空间,而且对于它们是什么来说大多是个谜。在 stackoverflow.com 上发布他们的第一个问题之前,每个人都应该采取tour,阅读help center,了解minimal reproducible exampleHow to Ask 问题的所有要求。
  • 如何让它“正确”?它想做什么,你打算如何使用它?这些是这里不清楚的。写出你试图“正确”的整个代码,包括你如何使用它
  • 好吧,没有人问你“如何让它编译”。你被要求显示一个minimal reproducible example,除了有问题的部分之外,所有东西都可以编译。在 Stackoverflow 上获得帮助的最佳方式是让其他人尽可能轻松地自己重现您的问题。以目前的形式,没有人能做到这一点,因为没有人知道这些神秘的 ss::array_helper 类型是什么,或者模板使用哪些参数进行实例化。你有没有使用 Stackoverflow 的 tour,阅读 help center,并了解 How to Ask 的问题?如果没有,为什么不呢?

标签: c++ c++20


【解决方案1】:

std::index_sequence 的用法是将其扩展为可变参数形式:

[&] template <std::size_t ... Is> (std::index_sequence<Is...>)
{
    ((res[Is] += rhs[Is]), ...);
} (std::make_index_sequence<std::min(sz, ssz)>{});

【讨论】:

  • 我只是想让你知道,你是个传奇。您并没有使我的问题脱轨,直截了当,并为我的问题提供了一个非常优雅的解决方案。我知道我的问题并没有很好地形成,但我只是想给出一个大致的要点。感谢您的善意并提供编写良好的解决方案。
  • @Valena “我知道我的问题不是很好” - 但你本可以(并且仍然可以)花时间改进你的问题清楚你在问什么。相反,您花时间对那些想提供帮助但由于问题质量低而无法提供帮助的人怀有敌意。
【解决方案2】:

非常有趣的问题。 Jarod42 已经展示了使用 C++20 的解决方案。但是,在 C++17 中,我们没有模板化的 lambda。

为了让你有一个 C++17 解决方案,我将介绍一个使用模板化成员函数进行加法的实现。

由于我不知道您对数据类型array_helper 的定义,因此我使用仅示例 版本并仅从std::array 派生,通常您不应该这样做。我在这里只是为了演示目的。

模板化的成员函数可以按预期定义:

    // Templated function that performs the addition
    template <typename TRight, size_t SizeRight, size_t ... indices>
    auto add(array_helper<T, Size>& left, array_helper<TRight, SizeRight>& right, std::index_sequence<indices...>) {
        array_helper<T, Size> result{};
        ((result[indices] = left[indices] + right[indices]), ...);
        return result;
    };

这并不奇怪。一个简单的实现。我们将调用覆盖的“+”运算符。


它的美妙之处在于我们现在可以添加不同类型和长度的数组。


所有这一切都导致了一个易于理解且在某种程度上简单的代码:

#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>

template <typename T, const size_t Size, size_t ... Is>
struct array_helper : public std::array<T,Size> {

    // Templated function that performs the addition
    template <typename TRight, size_t SizeRight, size_t ... indices>
    auto add(array_helper<T, Size>& left, array_helper<TRight, SizeRight>& right, std::index_sequence<indices...>) {
        array_helper<T, Size> result{};
        ((result[indices] = left[indices] + right[indices]), ...);
        return result;
    };

    // Override operator + for array_helper
    template <typename TOther, size_t SizeOther>
    auto operator + (array_helper<TOther, SizeOther>& other) {

        // Call templated member function
        return add(*this, other, std::make_index_sequence<std::min(SizeOther, Size)>{});
    }
};

int main() {
    // Some test variables
    array_helper<char, 4> array1{ 'a','b','c','d'  };
    array_helper<int, 3> array2{ 1,2,3 };
    
    // Call '+' operator
    auto array3 = array1 + array2;

    // Show debug output
    std::copy(array1.begin(), array1.end(), std::ostream_iterator<char>(std::cout, "\n")); std::cout << '\n';
    std::copy(array2.begin(), array2.end(), std::ostream_iterator<int>(std::cout, "\n")); std::cout << '\n';
    std::copy(array3.begin(), array3.end(), std::ostream_iterator<char>(std::cout, "\n")); std::cout << '\n';

    return 0;
}

使用 C++17 编译。

适用于

  • Microsoft Visual Studio 社区 2019,版本 16.8.2
  • clang 11.0.0 X86-64
  • gcc 10.2 X86-64

【讨论】:

  • 希望您知道,您是一个了不起的人。感谢您参与讨论并保持积极态度,即使我无法正确表达。不仅如此,您还为对话做出了贡献,并有一些有用的话要说。谢谢你,阿明总统。
猜你喜欢
  • 1970-01-01
  • 2012-11-26
  • 2021-12-08
  • 2023-01-16
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
相关资源
最近更新 更多