是否可以在不创建新数据结构的情况下执行此操作? 假设我们有
struct Span{
int from;
int to;
}
vector<Span> s;
我们希望通过强制转换
直接从s得到一个整数向量vector<Span> s;
到
vector<int> s;
所以我们可以删除/更改一些“from”,“to”元素,然后将其转换回
vector<Span> s;
答案 0 :(得分:2)
这不是一个好主意,但我会告诉你如何。
你可以通过这种方式得到一个指向整数的原始指针:
int * myPointer2 = (int*)&(s[0]);
但这实际上是不好的做法,因为你不能保证跨度结构没有任何padding,所以虽然它对我来说可能没什么用,但是今天我们对其他系统说不出多少
#include <iostream>
#include <vector>
struct Span{
int from;
int to;
};
int main()
{
std::vector<Span> s;
Span a = { 1, 2};
Span b = {2, 9};
Span c = {10, 14};
s.push_back(a);
s.push_back(b);
s.push_back(c);
int * myPointer = (int*)&(s[0]);
for(int k = 0; k < 6; k++)
{
std::cout << myPointer[k] << std::endl;
}
return 0;
}
正如我所说,重新解释强制转换通常会起作用但非常危险,缺乏您通常期望从C / C ++中获得的跨平台保证。
接下来更糟糕的是,这实际上会按照你的要求行事,但你永远不应该这样做。这是你可以解雇的代码:
// Baaaad mojo here: turn a vector<span> into a vector<int>:
std::vector<int> * pis = (std::vector<int>*)&s;
for ( std::vector<int>::iterator It = pis->begin(); It != pis->end(); It++ )
std::cout << *It << std::endl;
注意我是如何使用指向矢量的指针并指向矢量对象的地址。我希望两个载体的内部结构相同,我可以像这样使用它们。对我来说,这是有效的,虽然标准模板可能幸运地要求这样,但对于模板化的类通常不是这样(参见填充和模板特化)。
考虑复制数组(参见下面的参考文献2)或仅使用s 1。from和s [2] .to。
相关阅读:
答案 1 :(得分:1)
免责声明:我绝对不知道关于你想要做什么。我只是在做出有根据的猜测,并在此基础上展示可能的解决方案。希望我能猜对了,你不必用愚蠢的演员做疯狂的诡计。
如果你想从矢量中删除某个元素,你需要做的就是找到它并使用the erase
function删除它。您需要一个元素的迭代器,并获取该迭代器取决于您对所讨论元素的了解。鉴于std::vector<Span> v;
:
如果你知道它的索引:
v.erase(v.begin() + idx);
如果您的对象与您正在寻找的对象相同:
Span doppelganger;
v.erase(std::find(v.begin(), v.end(), doppelganger));
如果您的对象与您正在寻找的对象相同但想要删除所有相等的元素,则需要使用erase-remove惯用法:
Span doppelganger;
v.erase(std::remove(v.begin(), v.end(), doppelganger)),
v.end());
如果您有一些选择元素的标准:
v.erase(std::find(v.begin(), v.end(),
[](Span const& s) { return s.from == 0; }));
// in C++03 you need a separate function for the criterion
bool starts_from_zero(Span const& s) { return s.from == 0; }
v.erase(std::find(v.begin(), v.end(), starts_from_zero));
如果您有一些标准,并且想要删除符合该标准的所有元素,则需要再次使用erase-remove惯用法:
v.erase(std::remove_if(v.begin(), v.end(), starts_from_zero)),
v.end());
答案 2 :(得分:1)
如果sizeof(Span) == sizeof(int) * 2
(即Span
没有填充),那么您可以安全地使用reinterpret_cast<int*>(&v[0])
获取指向可以迭代的int
数组的指针。您可以保证基于每个编译器的无填充结构,GCC中为__attribute__((__packed__))
,Visual Studio中为#pragma pack
。
但是,有一种方法可以通过标准来保证。像这样定义Span
:
struct Span {
int endpoints[2];
};
endpoints[0]
和endpoints[1]
必需是连续的。为方便起见,添加一些from()
和to()
访问者,如果您愿意,但现在您可以使用reinterpret_cast<int*>(&v[0])
内容。
但是如果你要做很多这样的指针修改,你可能想要制作自己的vector
- 类似于这种处理方式的数据结构 - 提供更多安全保证的数据结构所以你可以避免出手。