I fully understand this question has been asked a lot, but I'm asking for a specific variation and my search-foo has given up, as I've only found algorithms that append one existing vector to another, but not one returned to from a function.
I have this function that lists all files in a directory:
vector<string> scanDir( const string& dir )
which may call itself internally (for subdirectories).
I need a short way of appending the returned value to the caller's vector. I have in my mind something like this (but of course it doesn't exist :( ):
vector<string> fileList;
//...
fileList.append( scanDir(subdirname) );
I fear that storing the return value and inserting it in fileList would bring performance badness. What I mean is this:
vector<string> temp( scanDir(subdirname) );
copy( temp.begin(), temp.end(), back_inserter(fileList) );
Thanks!
PS: I'm not forcing myself to using vector, any other container that performs equally well and can prevent the potential large copy operation is fine by me.
To insert/append a vector's elements to another vector, we use vector::insert() function. Syntax: //inserting elements from other containers vector::insert(iterator position, iterator start_position, iterator end_position);
Master C and Embedded C Programming- Learn as you go Sum up of all elements of a C++ vector can be very easily done by std::accumulate method. It is defined in <numeric> header. It accumulates all the values present specified in the vector to the specified sum.
Begin Initialize a vector v1 with its elements. Declare another vector v2. Make a for loop to copy elements of first vector into second vector by Iterative method using push_back(). Print the elements of v1.
The concatenation of vectors can be done by using combination function c. For example, if we have three vectors x, y, z then the concatenation of these vectors can be done as c(x,y,z). Also, we can concatenate different types of vectors at the same time using the same same function.
Why not just pass the vector as an argument? Then every invocation can append to the same vector, without copying. Or create an implementation class which accumulates the elements into a member object.
If you're in the position to change scanDir
, make it a (template) function accepting an output iterator:
template <class OutIt>
void scanDir(const std::string& dirname, OutIt it) {
// ...
// Scan subdir
scanDir(subdir, it);
// ...
}
You'll have the additional benefit to be able to fill all sort of data structures like
std::vector<string> vector;
scanDir(dir1, std::back_inserter(vector));
std::set<string> fileset
scanDir(dir1, std::inserter(fileset, fileset.begin()));
etc.
EDIT (see comment ...)
For using this function for class member initialization, you could either call it in the constructor as in
class MyClass {
private:
std::vector<string> m_fileList;
public:
MyClass(const std::string& dirname) {
scanDir(dirname, std::back_inserter(m_fileList);
}
}
or using a wrapper function
std::vector<string> scanDir(const std::string& dirname) {
std::vector<string> result;
scanDir(dirname, std::back_inserter(result);
return result;
}
class MyClass {
// Same as above..
MyClass(const std::string& dirname) : m_fileList(scanDir(dirname)) { }
}
I would prefer the first version for performance (and other) reasons ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With