gpt4 book ai didi

c++ - 获取多维访问的线性索引

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:05:43 25 4
gpt4 key购买 nike

我正在尝试实现一个多维 std::array,它包含大小为 Dim-n-1 * Dim-n-2 * ... * Dim-1 的连续内存数组。为此,我使用了 std::array 的私有(private)继承:

constexpr std::size_t factorise(std::size_t value)
{
return value;
}

template<typename... Ts>
constexpr std::size_t factorise(std::size_t value, Ts... values)
{
return value * factorise(values...);
}

template<typename T, std::size_t... Dims>
class multi_array : std::array<T, factorise(Dims...)>
{
// using directive and some stuff here ...

template<typename... Indexes>
reference operator() (Indexes... indexes)
{
return base_type::operator[] (linearise(std::make_integer_sequence<Dims...>(), indexes...)); // Not legal, just to explain the need.
}
}

例如,multi_array<5, 2, 8, 12> arr; arr(2, 1, 4, 3) = 12;将访问线性索引 idx = 2*(5*2*8) + 1*(2*8) + 4*(8) + 3 .

我想我必须使用 std::integer_sequence,将整数序列传递给线性化函数和索引列表,但我不知道该怎么做。我想要的是这样的:

template<template... Dims, std::size_t... Indexes>
auto linearise(std::integer_sequence<int, Dims...> dims, Indexes... indexes)
{
return (index * multiply_but_last(dims)) + ...;
}

使用 multiply_but_last 乘以除最后一个以外的所有剩余维度(我看到了如何使用 constexpr 可变参数模板函数来实现,例如 factorise,但我不明白是否可以使用 std::integer_sequence)。

我是可变参数模板操作和 std::integer_sequence 方面的新手,我认为我遗漏了一些东西。是否有可能在没有开销的情况下获得线性索引计算(即,如果操作是手写的)?

非常感谢您的帮助。

最佳答案

以下内容可能会有所帮助:

#include <array>
#include <cassert>
#include <iostream>

template <std::size_t, typename T> using alwaysT_t = T;

template<typename T, std::size_t ... Dims>
class MultiArray
{
public:
const T& operator() (alwaysT_t<Dims, std::size_t>... indexes) const
{
return values[computeIndex(indexes...)];
}
T& operator() (alwaysT_t<Dims, std::size_t>... indexes)
{
return values[computeIndex(indexes...)];
}

private:
size_t computeIndex(alwaysT_t<Dims, std::size_t>... indexes_args) const
{
constexpr std::size_t dimensions[] = {Dims...};
std::size_t indexes[] = {indexes_args...};

size_t index = 0;
size_t mul = 1;

for (size_t i = 0; i != sizeof...(Dims); ++i) {
assert(indexes[i] < dimensions[i]);
index += indexes[i] * mul;
mul *= dimensions[i];
}
assert(index < (Dims * ...));
return index;
}

private:
std::array<T, (Dims * ...)> values;
};

Demo

我用折叠表达式 (C++17) 替换了你的 factorize

关于c++ - 获取多维访问的线性索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50652056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com