[英]convert c multidimensional array to multidimensional c++ vector
我正在嘗試將 c 多維數組轉換為多維 c++ 向量,我的意思是,轉換像這樣的int arr[2][3] = {{1,2,3}, {4,5,6}};
進入對應的向量。
數組不一定是 2D 形狀的,它也可能是這樣的:
int arr[2][2][3] = {
{
{1,2,3},
{4,5,6},
},
{
{7,8,9},
{10,11,12},
}
};
最初我認為這樣的事情會起作用,但事實並非如此,因為似乎std::vector
不允許從 C arrays 進行轉換。
std::vector<std::any> V(arr);
然后我想到了 function 遞歸之類的東西,這是我的嘗試,(我不知道為什么!)拋出error: no matching function for call to 'length'
。
#include <iostream>
#include <type_traits>
#include <vector>
#include <any>
// Get the lenght of a classic C array.
template <class T, unsigned S>
inline unsigned length(const T (&v)[S]) {
return S;
};
// Check wether the input is a classic C array or not.
template <class T>
bool is(const T& t) {
return std::is_array_v<T>;
};
// Turn the classic C input array to vector.
template <class T>
std::vector<std::any> toVector(const T& t) {
std::vector<std::any> V;
for (int k = 0; k < length(t); k++) {
if (is(t[k])) {
V.push_back(toVector(t[k]));
} else {
V.push_back(t[k]);
}
}
return V;
}
int main() {
int16 a[] = {1,2,3};
auto b = toVector(a);
}
我在第二次嘗試中做錯了什么? 或者,有沒有更簡單的方法來做到這一點?
另外,我認為將向量中的所有數字轉換為唯一的給定數據類型會更好,這可能嗎?
我使用 c++11 和 g++ 作為編譯器 –
請注意,我不知道我的數組有多少維。
C 多維數組的等價物是平面 C++ 向量加上多維數組視圖。
朴素的等價物是向量的向量(可能是向量),它實際上對應於 C “鋸齒狀”數組。 memory 布局和性能特點會有很大不同。
web 上有許多多維數組視圖實現。
template<class A>
struct raw_ptr { using type=A*; };
template<class A, std::size_t N>
struct raw_ptr<A[N]>:raw_ptr<A>{};
template<class A>
using raw_ptr_t = typename raw_ptr<A>::type;
template<class T>
struct array_view;
template<class T, std::size_t D0, std::size_t D1>
struct array_view<T[D0][D1]> {
T(*data)[D1]=0;
constexpr array_view( T(&arr)[D0][D1] ):data(arr) {}
explicit array_view( raw_ptr_t<T> buff ):data(reinterpret_cast<T(*)[D1]>(buff)) {}
constexpr array_view<T[D1]> operator[](std::size_t i)const{
return data[i];
}
};
template<class T, std::size_t D0>
struct array_view<T[D0]> {
constexpr array_view( T(&arr)[D0] ):data(arr) {}
explicit constexpr array_view( T* buff ):data(buff) {}
T* data=0;
constexpr T& operator[](std::size_t i)const{
return data[i];
}
};
轉換一個int[4][5][6]
你會做:
int array[4][5][6]={/*whatever*/};
std::vector<int> buff(&array[0][0][0], &array[3][4][5]);
array_view<int[4][5][6]> view{buff.data()};
現在, view[a][b][c]
與array[a][b][c]
相同。
template<class Array>
struct wrap_array_in_vector {
using raw_ptr = raw_ptr_t<Array>;
using value_type = std::remove_pointer_t<raw_ptr>;
std::vector<value_type> data;
array_view<Array> view;
wrap_array_in_vector(wrap_array_in_vector const& other):
data(other.data),
view(data.data())
{}
wrap_array_in_vector(wrap_array_in_vector && other):
data(std::move(other.data)),
view(data.data())
{
other.view.data = nullptr; // no longer valid
}
decltype(auto) operator[](std::size_t i)const {
return view[i];
}
wrap_array_in_vector( Array const& arr ):
data( reinterpret_cast<value_type const*>(&arr[0]), reinterpret_cast<value_type const*>(&arr[1]) ),
view(data.data())
{}
};
template<class Array>
wrap_array_in_vector(Array&)->wrap_array_in_vector<Array>;
template<class Array>
wrap_array_in_vector(Array const&)->wrap_array_in_vector<Array>;
這讓你做
wrap_array_in_vector wrapped = array;
並且wrapped
推斷出它需要的所有類型信息。
這應該接近於轉換為向量的最佳值。 描述中誤導的部分是大小不規則,因為它們是列表初始化的,在這種情況下使用 int,將為零。
#include <type_traits>
#include <vector>
#include <iostream>
template<typename T, std::size_t N>
auto to_vectors( T const (&c_array)[N] ) {
using element_base_type = std::decay_t<T>;
if constexpr( std::is_array_v<T> ) {
using child_t = std::remove_cv_t<std::remove_reference_t<decltype( to_vectors( c_array[0] ) )>>;
auto result = std::vector<child_t>( );
result.reserve( N );
for( auto const & element: c_array ) {
result.push_back( to_vectors( element ) );
}
return result;
} else {
return std::vector<T>( c_array, c_array + N );
}
}
int arr[2][2][3] = {
{
{1,2,3},
{4,5,6},
},
{
{7,8,9},
}
};
auto v0 = to_vectors( arr );
template<typename Vec>
void display( Vec const & vec ) {
if constexpr( std::is_same_v<int, typename Vec::value_type> ) {
std::cout << "elements: {";
for( int e: vec ) {
std::cout << e << ',';
}
std::cout << "}\n";
} else {
std::cout << "element count: " << vec.size( ) << '\n';
for( auto const & child: vec ) {
display( child );
}
}
}
int main( ) {
display( v0 );
}
這將 output
element count: 2
element count: 2
elements: {1,2,3,}
elements: {4,5,6,}
element count: 2
elements: {7,8,9,}
elements: {0,0,0,}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.