以下解决方案使用了一些 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>>;
Test:
int main()
{
my_data<double, 4> vec(1,2,3,4);
vec(0,0,0,0) = 2.0;
}
DEMO http://coliru.stacked-crooked.com/a/6570aca0f11eb2e2
演示(C++11) http://coliru.stacked-crooked.com/a/6688d68b6f1eafa1