在不使用模板的情况下将多个大小的数组传递给虚拟方法
Passing multiple sized arrays to virtual method without using templates
所以我有一个纯虚拟类,需要保持这种状态。在此类中,我有或技术上需要一个接受模板化参数的方法。下面是参数的对象类型:
template <int LENGTH>
struct MyStruct
{
int arr[LENGTH];
};
这是我的方法:
template <int LENGTH>
virtual bool send_struct(const MyStruct<LENGTH>& mystruct) = 0;
但是,显然我不能将模板与虚拟类一起使用,另一种方法是将模板添加到类中,我也无法达到我的目的。在保持我的约束的同时,有没有其他选择?我需要在我的纯虚拟类中将不同大小的数组传递给此方法,但我无法模板化该类。
如你所知,你不能写这个:
template <int LENGTH>
virtual bool send_struct(const MyStruct<LENGTH>& mystruct) = 0;
无法通过编译时LENGTH
。但是,您可以通过类型擦除容器来传递运行时长度:
virtual bool send_struct(gsl::span<int const> ) = 0;
gsl::span<T>
是一个非拥有的、连续的 T
容器。它是对数组或vector
或其他任何东西的视图,也可以是MyStruct<N>
。此类型不能直接从您的结构中构造,但很容易编写一个版本,或者将必要的成员添加到您的结构(.data()
和.size()
)以使其工作。
一个非常简单的实现就是:
class my_span {
private:
int const* begin_;
int const* end_;
public:
template <int L>
my_span(MyStruct<L> const& ms)
: begin_(ms.arr)
, end_(ms.arr + L)
{ }
int const* begin() const { return begin_; }
int const* end() const { return end_; }
int const* data() const { return begin_; }
size_t size() const { return end_ - begin_; }
};
现在,对于一些不可修改的int
容器,您有一个易于覆盖的virtual
函数。
模板和虚拟方法相处得不好。您需要首先将MyStruct
的模板化部分与类的其余部分隔离开来,并且仅使用虚拟方法处理非模板部分。其次,您需要抽象模板化部分以提供虚拟方法可以使用的非模板接口。对于数组,这很容易。您可以简单地提供指针和大小。要在表示形式之间进行转换,请添加一个中间非虚拟模板化方法,该方法调用实际的非模板虚拟方法。
struct MyStruct
{
// All non-templated members
};
template <int LENGTH>
struct MyStructArray : public MyStruct
{
// All templated members
int arr[LENGTH];
};
struct OtherStruct
{
virtual bool send_struct_impl(const MyStruct& mystruct, const int * arr, int length) = 0;
template <int LENGTH>
bool send_struct(const MyStructArray<LENGTH>& mystruct)
{
return send_struct_impl(mystruct, mystruct.arr, LENGTH);
}
};
或者,如果您不介意开销,则可以在 MyStruct
中存储指针和大小以供MyStructArray::arr
。这将允许您在使用非模板引用或指向MyStruct
的指针的每个上下文中使用arr
。
struct MyStruct
{
protected:
MyStruct(int * p_arr_ptr, int p_arr_length) :
arr_ptr(p_arr_ptr), arr_length(p_arr_length) {}
public:
int * arr_ptr;
int arr_length;
// All other members
};
template <int LENGTH>
struct MyStructArray : public MyStruct
{
MyStructArray() : MyStruct(arr, LENGTH) {}
int arr[LENGTH];
};
你可以让MyStruct<int>
类型继承一个空的基类:
struct BaseStruct {};
template <int LENGTH>
struct MyStruct : BaseStruct
{
int arr[LENGTH];
};
并定义一个接受BaseStruct
和length
的虚函数:
virtual bool send_struct(const BaseStruct& mystruct, int length) = 0;
最终,您可以提供一个方便的功能来从这些BaseStruct
和length
转换为MyStruct<length>
:
template <int LENGTH>
const MyStruct<LENGTH>& to_mystruct(const BaseStruct& mystruct)
{
return static_cast<const MyStruct<LENGTH>&>(mystruct);
}
关于科里鲁的演示
- 初始化具有非默认构造函数的std::数组项的更好方法
- 复制几乎为空的数组的最快方法
- 通过JNI传递数据数组的最快方法是什么
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 数组元素打印的递归方法
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++数组队列实现方法错误
- 寻找一种更好的方法来表示无符号字符数组
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 创建异构顶点数据数组的可移植方法
- 打印字符数组地址的正确方法
- 还有其他方法可以在数组中写入多维数组吗?
- 从数组中删除非唯一值、保持顺序和不使用向量的最佳方法?
- 指针数组方法的向量push_back编译但不运行
- 在函数内部使用数组方法
- 如何获取方法内部int数组(方法参数)的长度
- 如何在c++中访问向量类数组方法