對于張量類,我希望有一個創建函式的模板,例如
double* mat(int size1);
double** mat(int size1, int size2);
double*** mat(int size1, int size2, int size3);
即回傳型別的指標級別取決于輸入的數量。基本情況只是
double* mat(int size1){
return new double[size1];
}
我認為可變引數模板可以以某種方式解決問題
template<typename T, typename... size_args>
T* mat(int size1, size_args... sizes) {
T* m = new T[size1];
for(int j = 0; j < size1; j ){
m[j] = mat(sizes...);
}
return m;
}
推導模板引數 inm[j] = mat(sizes...);似乎不起作用,但當需要多個遞回呼叫時,如
auto p = mat<double**>(2,3,4);
但是我如何在遞回呼叫中提供引數?正確的引數應該是下一級指標T,即mat<double**>for T=double***。我覺得我在這里錯過了一些關于模板的重要內容。
uj5u.com熱心網友回復:
您不能宣告m和回傳型別,T*因為它不是多維的。
template<typename T, typename size_type>
auto mat(size_type size){return new T[size];}
template<typename T, typename size_type, typename... size_types>
auto mat(size_type size, size_types... sizes){
using inner_type = decltype(mat<T>(sizes...));
inner_type* m = new inner_type[size];
for(int j = 0; j < size; j ){
m[j] = mat<T>(sizes...);
}
return m;
}
uj5u.com熱心網友回復:
由于沒有更好的名稱,我將呼叫模板元函式,它創建具有所需“深度”和型別的指標型別,即“遞回指標”。這樣的事情可以這樣實作:
template <size_t N, class T>
struct RecursivePtr
{
using type = RecursivePtr<N-1, T>::type*;
};
template <class T>
struct RecursivePtr<0, T>
{
using type = T;
};
template <size_t N, class T>
using recursive_ptr_t = RecursivePtr<N, T>::type;
recursive_ptr_t<4, int>例如創建int****. 因此,在您的情況下,您可以繼續將mat功能實作為:
template <class... Args>
auto mat(Args... args)
{
recursive_ptr_t<sizeof...(Args), double> m;
// Runtime allocate your Npointer here.
return m;
}
演示
為 mat 函式增加型別安全性的一些想法是:
- 添加靜態斷言所有提供的型別都是大小
- 靜態斷言至少提供了一種尺寸
小注意,當我說運行時在上面分配你的 Npointer 時,我的意思是:
template <class T, class... Sz>
void alloc_ar(T* &ar, size_t s1, Sz... ss)
{
if constexpr (sizeof...(Sz))
{
ar = new T[s1];
for (size_t i(0); i < s1; i )
alloc_ar(ar[i], ss...);
}
else
{
ar = new T[s1];
}
}
做了一個演示,我在其中顯示分配,但不顯示釋放。
一個合理的替代方案是分配一個連續的記憶體塊(大小==維度的乘積)并在訪問它時使用指向該塊開頭的多維指標作為語法糖。這也提供了一種更簡單的方法來釋放記憶體。
第二種選擇是使用與 Npointer 相同的生成機制的嵌套向量(向量的向量......)。這消除了手動記憶體管理的需要,并且可能會迫使您將整個事物包裝在一個更具表現力的類中:
template <class... Dims>
class mat
{
template <size_t N, class T>
struct RecursivePtr
{
using type = std::vector<RecursivePtr<N-1, T>::type>;
};
template <class T>
struct RecursivePtr<0, T>
{
using type = T;
};
// This is the replacement to double***
// translates to vector<vector<vector<double>>>
RecursivePtr<N, T>::type _data;
public:
// construction, argument deduction etc ...
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/462807.html
上一篇:C陣列中的指標應用
下一篇:Go賦值涉及到自定義型別的指標
