I have function in C++ that takes a vector and pushes some items onto it. For example:
void MyFunction(vector<int>* output);
I want to modify it to be able to now take a vector or a hash_set. In Java, this would be easy, simply change the function to take a Collection (the common开发者_StackOverflow interface). All MyFunction
does is put elements into the container it is given, so it shouldn't have to care whether that container is a vector or a hash_set, only that there is some notion of "inserting" an element.
Thanks for your help!
He'd have a small issue doing a straight-up template. Vector typically uses push_back while hash_set would use insert.
Use a template, but use the insert function and insert at the .end() element so that the vector maintains fast operations - its your best bet. You'll still slow down your hash-set a little though if it takes the insertion position as a hint of location (it'll work though).
Using insert(iter, val), the contianer is extended by inserting new elements before the element at the iterator position. This is true for sequence containers (vector) while associative containers (hash_set) will just use the position as a hint - but the insertion will still work fine. The function below could be used to insert value U into any container supporting insert (all STL ones do) assuming U is the same as or implicitly convertible to the vector element type.
template <typename T, typename U>
void InsertToContainer(T& container, U val)
{
container.insert(container.end(), val);
}
If I understand correctly, You can use Boost::Variant
A function template would allow you to make it more generic:
template<typename T, typename Cont = std::vector<T> > void MyFunction(T t, Cont c);
Here the default container would be std::vector<T>
, but you could still change the container if you wanted to.
If you need to use methods that are not common between the two containers, you can create two derived wrapper classes with a pure virtual base class that defines a common interface for operations you would like to-do with a unordered_set
and a vector
that do not have simliar method names, and then pass pointers or references to the base-class to the function.
For instance, your pure virtual base-class can define methods for inserting, finding, iterating, etc., and can mask the differences in the method names and uses of the methods between these two containers that perform these types of operations. Your derived types would be the actual implementation of the pure virtual methods in the base-class. Your function would take a reference or pointer to the base-type, and since the base-class is polymorphic, you can just call the interface methods that the base-class defines, and use both vector
and unordered_set
with your function without worrying about implementation differences and interface mis-matches between linear containers and associative containers.
精彩评论