插入一个从函数返回的std :: vector(Inserting a std::vector as returned from a function)

我发现自己经常做这样的事情来连接从函数返回的几个向量(可能是类函数):

#include <vector> #include <iostream> using namespace std; vector<int> v1; const vector<int>& F1() { cout << "F1 was called" << endl; /*Populate v1, which may be an expensive operation*/ return v1; } int main() { vector<int> Concat; Concat.insert(Concat.end(), F1().begin(), F1().end()); /*Do something with Concat*/ return 0; }

正如我所料, F1()被调用两次,如果它是一个昂贵的函数调用,这可能是不可取的。 另一种方法是将F1()的返回值复制到一个临时向量中,该向量只需要一个函数调用,但是如果向量很大则会产生复制操作。 我能想到的唯一另一种选择是创建一个指向临时向量的指针,并将F1()的返回值分配给它,如下所示:

int main() { vector<int> Concat; const vector<int>* temp = &F1(); Concat.insert(Concat.end(), temp->begin(), temp->end()); /*Do something with Concat*/ return 0; }

这真的是最好的解决方案吗? 使用临时变量似乎很麻烦,特别是如果我需要连接几个向量。 我也觉得应该有一种方法来使用引用而不是指针来做到这一点。 有什么建议么?

I find myself frequently doing something like this to concatenate several vectors that are returned from functions (possibly class functions):

#include <vector> #include <iostream> using namespace std; vector<int> v1; const vector<int>& F1() { cout << "F1 was called" << endl; /*Populate v1, which may be an expensive operation*/ return v1; } int main() { vector<int> Concat; Concat.insert(Concat.end(), F1().begin(), F1().end()); /*Do something with Concat*/ return 0; }

As I expected, F1() is called twice, which may be undesirable if it is an expensive function call. An alternative is to copy the return value of F1() into a temporary vector which would only require one function call, but would incur a copy operation which might be undesirable if the vector is large. The only other alternative I can think of is to create a pointer to a temporary vector and assign the return value of F1() to it like this:

int main() { vector<int> Concat; const vector<int>* temp = &F1(); Concat.insert(Concat.end(), temp->begin(), temp->end()); /*Do something with Concat*/ return 0; }

Is this really the best solution? The use of a temporary variable seems cumbersome, especially if I need to concatenate several vectors. I also feel like there should be a way to do this using references instead of pointers. Any suggestions?

最满意答案

最好的解决方案是不首先直接使用vector ,而是使用OutputIterator和std::back_inserter 。

template <typename OutputIterator> OutputIterator F1( OutputIterator out ) { cout << "F1 was called" << endl; /* Insert stuff via *out++ = ...; */ *out++ = 7; return out; } int main() { std::vector<int> Concat; // perhaps reserve some moderate amount of storage to avoid reallocation F1( std::back_inserter(Concat) ); F1( std::back_inserter(Concat) ); }

演示 。 这样就实现了最大的效率和灵活性。

The best solution is not to use vector directly in the first place but OutputIterators and std::back_inserter.

template <typename OutputIterator> OutputIterator F1( OutputIterator out ) { cout << "F1 was called" << endl; /* Insert stuff via *out++ = ...; */ *out++ = 7; return out; } int main() { std::vector<int> Concat; // perhaps reserve some moderate amount of storage to avoid reallocation F1( std::back_inserter(Concat) ); F1( std::back_inserter(Concat) ); }

Demo. This way maximum efficiency and flexibility are achieved.

插入一个从函数返回的std :: vector(Inserting a std::vector as returned from a function)

我发现自己经常做这样的事情来连接从函数返回的几个向量(可能是类函数):

#include <vector> #include <iostream> using namespace std; vector<int> v1; const vector<int>& F1() { cout << "F1 was called" << endl; /*Populate v1, which may be an expensive operation*/ return v1; } int main() { vector<int> Concat; Concat.insert(Concat.end(), F1().begin(), F1().end()); /*Do something with Concat*/ return 0; }

正如我所料, F1()被调用两次,如果它是一个昂贵的函数调用,这可能是不可取的。 另一种方法是将F1()的返回值复制到一个临时向量中,该向量只需要一个函数调用,但是如果向量很大则会产生复制操作。 我能想到的唯一另一种选择是创建一个指向临时向量的指针,并将F1()的返回值分配给它,如下所示:

int main() { vector<int> Concat; const vector<int>* temp = &F1(); Concat.insert(Concat.end(), temp->begin(), temp->end()); /*Do something with Concat*/ return 0; }

这真的是最好的解决方案吗? 使用临时变量似乎很麻烦,特别是如果我需要连接几个向量。 我也觉得应该有一种方法来使用引用而不是指针来做到这一点。 有什么建议么?

I find myself frequently doing something like this to concatenate several vectors that are returned from functions (possibly class functions):

#include <vector> #include <iostream> using namespace std; vector<int> v1; const vector<int>& F1() { cout << "F1 was called" << endl; /*Populate v1, which may be an expensive operation*/ return v1; } int main() { vector<int> Concat; Concat.insert(Concat.end(), F1().begin(), F1().end()); /*Do something with Concat*/ return 0; }

As I expected, F1() is called twice, which may be undesirable if it is an expensive function call. An alternative is to copy the return value of F1() into a temporary vector which would only require one function call, but would incur a copy operation which might be undesirable if the vector is large. The only other alternative I can think of is to create a pointer to a temporary vector and assign the return value of F1() to it like this:

int main() { vector<int> Concat; const vector<int>* temp = &F1(); Concat.insert(Concat.end(), temp->begin(), temp->end()); /*Do something with Concat*/ return 0; }

Is this really the best solution? The use of a temporary variable seems cumbersome, especially if I need to concatenate several vectors. I also feel like there should be a way to do this using references instead of pointers. Any suggestions?

最满意答案

最好的解决方案是不首先直接使用vector ,而是使用OutputIterator和std::back_inserter 。

template <typename OutputIterator> OutputIterator F1( OutputIterator out ) { cout << "F1 was called" << endl; /* Insert stuff via *out++ = ...; */ *out++ = 7; return out; } int main() { std::vector<int> Concat; // perhaps reserve some moderate amount of storage to avoid reallocation F1( std::back_inserter(Concat) ); F1( std::back_inserter(Concat) ); }

演示 。 这样就实现了最大的效率和灵活性。

The best solution is not to use vector directly in the first place but OutputIterators and std::back_inserter.

template <typename OutputIterator> OutputIterator F1( OutputIterator out ) { cout << "F1 was called" << endl; /* Insert stuff via *out++ = ...; */ *out++ = 7; return out; } int main() { std::vector<int> Concat; // perhaps reserve some moderate amount of storage to avoid reallocation F1( std::back_inserter(Concat) ); F1( std::back_inserter(Concat) ); }

Demo. This way maximum efficiency and flexibility are achieved.