我正在用 C 撰寫一個任意排序的張量(多維陣列)類,并希望擁有它的靜態和動態記憶體版本。但是,考慮到基礎資料容器會有所不同,我正在努力想辦法避免在類的靜態/動態版本中重復方法。我希望以下最小的例子能說明我的觀點:
// Product function
template <typename ...data_type>
constexpr auto Product(data_type ..._values)
{
return (_values * ...);
}
// Static memory version
template <class t_data_type, unsigned ...t_dimensions>
class StaticTensor
{
private:
std::array<t_data_type, Product(t_dimensions...)> Entries; // Store entries as contiguous memory
public:
StaticTensor() = default;
~StaticTensor() = default;
void StaticMethod()
{
// Some code that operates on Entries.
}
};
// Dynamic memory version
template <class t_data_type>
class DynamicTensor
{
private:
std::vector<t_data_type> Entries;
public:
DynamicTensor() = default;
~DynamicTensor() = default;
template <typename ...t_dimensions>
void Resize(t_dimensions ...dims)
{
Entries.resize(Product(dims...));
}
void DynamicMethod()
{
// Some code that operates on Entries.
}
};
我已經考慮過基于繼承/多型的方法,但似乎我仍然需要在每個專門的類中實作單獨的方法。理想情況下,我希望所有方法都可以對std::arrayand 中的底層迭代器進行操作std::vector,而不必擔心它們屬于哪個資料容器。任何人都可以建議我如何去做嗎?
uj5u.com熱心網友回復:
您可以使用CRTP技術來創建TensorBase,然后再轉換*this到Derived&訪問派生類的Entries內部Method():
template <class Derived>
class TensorBase
{
public:
void Method()
{
auto& Entries = static_cast<Derived&>(*this).Entries;
// Some code that operates on Entries.
}
};
然后您StaticTensor/DynamicTensor可以繼承TensorBase以獲取Method(). 為了讓基類能夠訪問私有成員,還需要將基類設定為友元:
// Static memory version
template <class t_data_type, unsigned ...t_dimensions>
class StaticTensor
: public TensorBase<StaticTensor<t_data_type, t_dimensions...>>
{
using Base = TensorBase<StaticTensor<t_data_type, t_dimensions...>>;
friend Base;
private:
std::array<t_data_type, Product(t_dimensions...)> Entries;
public:
StaticTensor() = default;
~StaticTensor() = default;
};
// Dynamic memory version
template <class t_data_type>
class DynamicTensor
: public TensorBase<DynamicTensor<t_data_type>>
{
using Base = TensorBase<DynamicTensor<t_data_type>>;
friend Base;
private:
std::vector<t_data_type> Entries;
public:
DynamicTensor() = default;
~DynamicTensor() = default;
};
演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/314609.html
