So I have the following code that makes it possible to "search" for a string of an object in a vector.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
struct migObj
{
migObj(const std::string& a_name, const std::string& a_location) : name(a_name), location(a_location) {}
std::string name;
std::string location;
};
int main()
{
typedef std::vector<migObj> migVec;
migVec v;
v.push_back(migObj("fred", "belfast"));
v.push_back(migObj("ivor", "london"));
// Search by name.
const std::string name_to_find = "ivor";
auto i = std::find_if(v.begin(), v.end(), [&](const migObj& obj) { return name_to_find == obj.name;});
if (i != v.end())
{
std::cout << i->name << ", " << i->location << "\n";
}
return 0;
}
The code below the commecnt "search by name" is responsible for this result. What I want to do is make a method that is either added to the std::vector or to the typedef migVec, so I can call
v.myNewSearchFunction("ivor");
You can't do that: C++ doesn't have extension methods similar to what you have in C#.
You could derive your class from vector, but then you have to change all the client code. Besides, as Roddy points out, std::vector doesn't have a virtual destructor, so deriving from it is a bad idea in general.
IMO, writing a simple function would be much better choice. Additional benefit is that it would also work for most other containers (e.g. std::list
) and be more compatible with most of algorithms in STL which are also typically free functions.
So you would have this instead:
myNewSearchFunction(v, "ivor"); // instead of v.myNewSearchFunction("ivor");
Internally, this function does std::find_if(v.begin(), v.end(), ...
.
BTW, please note that it would be better to use std::begin(v), std::end(v)
than v.begin(), v.end()
. This lets you run the same code on e.g. arrays.
Putting things into classes isn't always the best choice in C++.
That's not possible. At least not in any way that is recommendable.
To elaborate a bit: You cannot "extend" C++ classes to have more methods than in their primary definition. In other words, you cannot redefine the class or "reopen" its definition to add more features.
What you should do: Write a free function, taking the vector as first parameter. That is as good as writing a method, has no caveats. The generated assembler would likely be identical to a new method:
migVec::const_iterator findByName(migvec const& mv, std::string const& name) {
return std::find_if(std::cbegin(mv), std::cend(mv), [&](const migObj& obj) {
return name == obj.name;
});
}
//...
auto pos = findByName(v, "ivor");
What you could theoretically do but shouldn't:
std::vector
. Don't do this. It's not designed to be derived from, and you could run into tons of trouble.std::vector<migObj>
. It is allowed to provide full specializations of standard library templates. However, you'd have to provide the complete definition of the specialized vector, meaning alls its standard methods and the new method you want it to have. To achieve this, you'd either have to practically copy std::vector
's defintion from your library header (wich is not portable) or roll your own definition, wich is tedious work. Just don't go there.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