C++11 基于std::vector的N维张量

C++11 基于std::vector的N维张量,c++11,C++11,我想使用std::vector定义n维数据结构。运算符()的定义有问题。让我们看一看示例二维结构 class my_data { public: my_data (size_t N, size_t M) : tab(N*M), _N(N), _M(M) {} const double& operator() (size_t i, size_t j) const { return tab.at(i * M + j); } double& operat

我想使用std::vector定义n维数据结构。运算符()的定义有问题。让我们看一看示例二维结构

class my_data {

public:
  my_data (size_t N, size_t M) : tab(N*M), _N(N), _M(M) {}

  const double& operator() (size_t i, size_t j) const {
     return tab.at(i * M + j);
  }

  double& operator() (size_t i, size_t j) {
     return tab.at(i * M + j);
  }

private:
   std::vector<double> tab;
   size_t _N;
   size_t _M;

};

下面的解决方案使用了一些C++14和C++1z功能,但它们可以轻松移植到C++11:

#include <vector>
#include <utility>
#include <array>
#include <cstddef>

namespace detail
{
    template <typename T, typename S>
    class my_data;

    template <typename T, std::size_t... Is>
    class my_data<T, std::index_sequence<Is...>>
    {
    public:
        my_data(decltype(Is)... size)
            : t((size * ...)), s{{ size... }}
        {}

        T& operator()(decltype(Is)... i)
        {            
            return t.at(index({{ i... }}));
        }

        const T& operator()(decltype(Is)... i) const
        {            
            return t.at(index({{ i... }}));
        }

    private:
        std::size_t index(const std::array<std::size_t, sizeof...(Is)>& a) const
        {
            std::size_t ind = a[0];
            for (std::size_t i = 1; i < a.size(); ++i)
            {
                ind = ind * s[i] + a[i];
            }
            return ind;
        }

        std::vector<T> t;
        const std::array<std::size_t, sizeof...(Is)> s;
    };
}

template <typename T, std::size_t N>
using my_data = detail::my_data<T, std::make_index_sequence<N>>;
#包括
#包括
#包括


Piotr Skotnicki干得不错。我还有一个额外的问题:如何使此数据结构与任何数据类型(而不仅仅是双精度)一起运行?@Bociek我已将解决方案细化为bitHello@PiotrSkotnicki。我想在my_data类中定义一个函数,该函数返回my_数据,但大小较小。特别是大小为N的my_数据应该有一个返回大小为N-1的my_数据的函数。你知道如何写返回类型my_data(我应该在点中输入什么)?@Bociek
my_data one_minger(),您要用一些数据填充这个较小的实例吗?谢谢。是的,我会的,但我愿意为此使用迭代器。
vec (0,0,0,0) = 2.0;
#include <vector>
#include <utility>
#include <array>
#include <cstddef>

namespace detail
{
    template <typename T, typename S>
    class my_data;

    template <typename T, std::size_t... Is>
    class my_data<T, std::index_sequence<Is...>>
    {
    public:
        my_data(decltype(Is)... size)
            : t((size * ...)), s{{ size... }}
        {}

        T& operator()(decltype(Is)... i)
        {            
            return t.at(index({{ i... }}));
        }

        const T& operator()(decltype(Is)... i) const
        {            
            return t.at(index({{ i... }}));
        }

    private:
        std::size_t index(const std::array<std::size_t, sizeof...(Is)>& a) const
        {
            std::size_t ind = a[0];
            for (std::size_t i = 1; i < a.size(); ++i)
            {
                ind = ind * s[i] + a[i];
            }
            return ind;
        }

        std::vector<T> t;
        const std::array<std::size_t, sizeof...(Is)> s;
    };
}

template <typename T, std::size_t N>
using my_data = detail::my_data<T, std::make_index_sequence<N>>;
int main()
{        
    my_data<double, 4> vec(1,2,3,4);
    vec(0,0,0,0) = 2.0;
}