是否可以创建不同的派生 classes,它们共享对每个派生 class 唯一的成员变量进行操作的相同方法?
Is it possible to create different derived classes sharing the same methods that operate on member variables unique to each derived class?
我正在用 C++ 编写一个任意排序的张量(多维数组)class,并且想要它的静态和动态内存版本。但是,我正在努力想办法避免在 class 的 static/dynamic 版本中重复方法,考虑到底层数据容器会有所不同。我希望以下最小示例能说明我的观点:
// 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.
}
};
我考虑过 inheritance-based/polymorphic 方法,但似乎我仍然需要在每个专门的 class 中实现单独的方法。理想情况下,我希望所有方法都对 std::array
和 std::vector
中的底层迭代器进行操作,而不必担心它们属于哪个数据容器。谁能建议我该怎么做?
您可以使用CRTP技术创建TensorBase
,然后将*this
转换为Derived&
以访问派生的class的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()
。为了使基class可以访问私有成员,还需要将基class设置为好友:
// 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;
};
我正在用 C++ 编写一个任意排序的张量(多维数组)class,并且想要它的静态和动态内存版本。但是,我正在努力想办法避免在 class 的 static/dynamic 版本中重复方法,考虑到底层数据容器会有所不同。我希望以下最小示例能说明我的观点:
// 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.
}
};
我考虑过 inheritance-based/polymorphic 方法,但似乎我仍然需要在每个专门的 class 中实现单独的方法。理想情况下,我希望所有方法都对 std::array
和 std::vector
中的底层迭代器进行操作,而不必担心它们属于哪个数据容器。谁能建议我该怎么做?
您可以使用CRTP技术创建TensorBase
,然后将*this
转换为Derived&
以访问派生的class的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()
。为了使基class可以访问私有成员,还需要将基class设置为好友:
// 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;
};