c++ vector of pointers 指向 vector of pointers ordering
c++ vector of pointers to vector of pointers ordering
我有两个 classes,每个都有一个指向 Data
的指针向量。我想要做的是将 class Sample2
向量中的指针分配给 class Sample1
向量中的指针。
问题是当我在第二个向量中分配指针时,它们在 中的存储顺序是第一个向量的顺序。我想按插入顺序存储它们。
下面是一个minimal reproducible example的代码:
#include <iostream>
#include <vector>
using namespace std; //for sample purposes
// For simplicity, the data is just a string in this example.
using Data = string;
// In the real code there is a class with a certain vector as a member,
// but for this example we can reduce it to just the vector.
using Sample1 = vector<Data*>;
Class Sample2 — 问题就在这里
class Sample2 {
vector<Data*> autodromos2;
public:
vector<Data*>& getAutodromos() { return autodromos2; }
// ** This is the function with the problem. **
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (Data* a : autodromos) {
for (string &s : arguments) {
if (s == *a) { // The real test is more complex.
getAutodromos().push_back(a);
break;
}
}
}
}
};
主要函数(生成数据并调用addAutodromos2
)
int main()
{
// Create the list of elements to add to a `Sample2`.
// Note that these are strings, not Data objects (in the real code).
vector<string> arguments { "fourth", "first", "third" };
// Create the `Sample1` data with which to work.
Sample1 s1 {
new Data("first"), new Data("second"), new Data("third"),
new Data("fourth"), new Data("fifth")
};
// Create the `Sample2` data from the list and `s1`.
Sample2 s2;
s2.addAutodromos2(arguments, s1);
// Diagnostic:
for (Data* a : s2.getAutodromos()) {
cout << *a << endl;
}
}
输出为
first
third
fourth
什么时候应该
fourth
first
third
实际上addAutodromos2()
中循环的顺序问题你需要用下面的代码改变函数:
for (string s : arguments)
{
for (Data* a : autodromos)
{
if (s == *a) { // The real test is more complex.
getAutodromos().push_back(a);
break;
}
}
}
切换 for 循环。输出是 fourth first third
希望这会有所帮助。
有一种观点认为,如果函数中有嵌套循环,则可能是你的思维不够抽象。虽然有时这可能是夸大其词,但在这种情况下它确实有价值。让我们看看内部循环。
for (string s : arguments) {
if (s == *a) {
getAutodromos().push_back(a);
break;
}
}
此循环在 arguments
中搜索 *a
,如果找到则执行某些操作。搜索是一个可以抽象到它自己的函数中的概念,我们称它为 found
,一个 return 是 bool
.
的函数
// Preliminary revision
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (Data* a : autodromos) {
if ( found(arguments, *a) ) {
getAutodromos().push_back(a);
}
}
}
只看一个循环,应该更清楚是什么问题了。元素按照它们在 autodromos
中出现的顺序添加到 getAutodromos()
。要使用 arguments
内的顺序,您需要循环遍历它。 (我将辅助函数的名称更改为 find_by_name
并使其 return 成为找到的元素的迭代器或结束迭代器。布尔值 return 不再足够。 )
// Final revision
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (string s : arguments) {
auto result = find_by_name(autodromos, s);
if ( result != autodromos.end() ) {
getAutodromos().push_back(*result);
}
}
}
此处缺少的部分是 find_by_name
函数。好消息是这个任务在 header <algorithm>
中很常见,that functionality is part of the standard library。坏消息是使用库函数需要一些输入,因为参数更复杂(为了更大的灵活性)。您可能想要定义一个包装器以专门针对您的情况。
// Returns an iterator to the element with the indicated name, or
// autodromos.end() if not found.
static auto find_by_name(const vector<Data*> & autodromos, const string & name)
{
return std::find_if(autodromos.begin(), autodromos.end(), [&name](Data *a){
return name == *a; // or name == a->get_name(), when Data is more complex
});
}
请注意,如果真正的测试就像比较 name == *a
一样简单,那么可以使用 std::find
代替 std::find_if
,并且不需要使用 lambda。
不要忘记在文件前面 #include <algorithm>
。
我有两个 classes,每个都有一个指向 Data
的指针向量。我想要做的是将 class Sample2
向量中的指针分配给 class Sample1
向量中的指针。
问题是当我在第二个向量中分配指针时,它们在 中的存储顺序是第一个向量的顺序。我想按插入顺序存储它们。
下面是一个minimal reproducible example的代码:
#include <iostream>
#include <vector>
using namespace std; //for sample purposes
// For simplicity, the data is just a string in this example.
using Data = string;
// In the real code there is a class with a certain vector as a member,
// but for this example we can reduce it to just the vector.
using Sample1 = vector<Data*>;
Class Sample2 — 问题就在这里
class Sample2 {
vector<Data*> autodromos2;
public:
vector<Data*>& getAutodromos() { return autodromos2; }
// ** This is the function with the problem. **
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (Data* a : autodromos) {
for (string &s : arguments) {
if (s == *a) { // The real test is more complex.
getAutodromos().push_back(a);
break;
}
}
}
}
};
主要函数(生成数据并调用addAutodromos2
)
int main()
{
// Create the list of elements to add to a `Sample2`.
// Note that these are strings, not Data objects (in the real code).
vector<string> arguments { "fourth", "first", "third" };
// Create the `Sample1` data with which to work.
Sample1 s1 {
new Data("first"), new Data("second"), new Data("third"),
new Data("fourth"), new Data("fifth")
};
// Create the `Sample2` data from the list and `s1`.
Sample2 s2;
s2.addAutodromos2(arguments, s1);
// Diagnostic:
for (Data* a : s2.getAutodromos()) {
cout << *a << endl;
}
}
输出为
first
third
fourth
什么时候应该
fourth
first
third
实际上addAutodromos2()
中循环的顺序问题你需要用下面的代码改变函数:
for (string s : arguments)
{
for (Data* a : autodromos)
{
if (s == *a) { // The real test is more complex.
getAutodromos().push_back(a);
break;
}
}
}
切换 for 循环。输出是 fourth first third
希望这会有所帮助。
有一种观点认为,如果函数中有嵌套循环,则可能是你的思维不够抽象。虽然有时这可能是夸大其词,但在这种情况下它确实有价值。让我们看看内部循环。
for (string s : arguments) {
if (s == *a) {
getAutodromos().push_back(a);
break;
}
}
此循环在 arguments
中搜索 *a
,如果找到则执行某些操作。搜索是一个可以抽象到它自己的函数中的概念,我们称它为 found
,一个 return 是 bool
.
// Preliminary revision
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (Data* a : autodromos) {
if ( found(arguments, *a) ) {
getAutodromos().push_back(a);
}
}
}
只看一个循环,应该更清楚是什么问题了。元素按照它们在 autodromos
中出现的顺序添加到 getAutodromos()
。要使用 arguments
内的顺序,您需要循环遍历它。 (我将辅助函数的名称更改为 find_by_name
并使其 return 成为找到的元素的迭代器或结束迭代器。布尔值 return 不再足够。 )
// Final revision
void addAutodromos2(vector<string>& arguments, vector<Data*>& autodromos)
{
for (string s : arguments) {
auto result = find_by_name(autodromos, s);
if ( result != autodromos.end() ) {
getAutodromos().push_back(*result);
}
}
}
此处缺少的部分是 find_by_name
函数。好消息是这个任务在 header <algorithm>
中很常见,that functionality is part of the standard library。坏消息是使用库函数需要一些输入,因为参数更复杂(为了更大的灵活性)。您可能想要定义一个包装器以专门针对您的情况。
// Returns an iterator to the element with the indicated name, or
// autodromos.end() if not found.
static auto find_by_name(const vector<Data*> & autodromos, const string & name)
{
return std::find_if(autodromos.begin(), autodromos.end(), [&name](Data *a){
return name == *a; // or name == a->get_name(), when Data is more complex
});
}
请注意,如果真正的测试就像比较 name == *a
一样简单,那么可以使用 std::find
代替 std::find_if
,并且不需要使用 lambda。
不要忘记在文件前面 #include <algorithm>
。