不用创建新的数据结构,是否有可能实现这个功能呢? 假设我们有
struct Span{
int from;
int to;
}
vector<Span> s;
我们希望通过转换,直接从s中获取一个整数向量。
vector<Span> s;
为了
vector<int> s;
因此,我们可以删除/更改一些“from”、“to”元素,然后将其转换回。
vector<Span> s;
不用创建新的数据结构,是否有可能实现这个功能呢? 假设我们有
struct Span{
int from;
int to;
}
vector<Span> s;
vector<Span> s;
为了
vector<int> s;
因此,我们可以删除/更改一些“from”、“to”元素,然后将其转换回。
vector<Span> s;
int * myPointer2 = (int*)&(s[0]);
#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;
}
// 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;
reinterpret_cast<int(*)[2]>(&s[0]);
,然后使用下标运算符访问各个成员。但是,我认为这仍然是可怕的未定义行为。 - Xeoint * myPointer2 = &(s[0].from);
。在实践中,它将在任何sizeof (Span) = 2 * sizeof (int)
的系统上工作,因为这使得所有指针数学计算结果相同。 - Ben Voigtsizeof(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
的数据结构,更易于进行此处理,提供更多安全保证,以避免出错。erase
函数将其删除即可。你需要一个指向该元素的迭代器,而获取该迭代器取决于你对该元素的了解。给定std::vector<Span> v;
:
如果您知道它的索引:
v.erase(v.begin() + idx);
如果您有一个与要查找的对象相等的对象:
Span doppelganger;
v.erase(std::find(v.begin(), v.end(), doppelganger));
如果您有一个与您要查找的对象相等但想要删除所有相同元素的对象,则需要使用擦除-移除习惯用法:
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; }));
// 在 C++03 中,您需要一个单独的函数来确定标准
bool starts_from_zero(Span const& s) { return s.from == 0; }
v.erase(std::find(v.begin(), v.end(), starts_from_zero));
如果您有一些标准并且想要删除所有符合该标准的元素,则再次需要使用擦除-移除习惯用法:
v.erase(std::remove_if(v.begin(), v.end(), starts_from_zero)),
v.end());
vector<something>
转换成一个vector<other>
,然后从这个vector<other>
中获取一些other
,然后再将其转换回vector<something>
。但我不认为这是可能的。我非常确定,在Java中,这将是一个非常错误的操作,而且我不认为你可以在C++中做到这一点。 - blahman