Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to overload a string as a vector of char elements?

Tags:

c++

I have a class which acts on a list of elements, like so:

template <typename T>
class MyClass {
    ...
};

I need to implement certain methods, that work both on a vector<T> and a string - which is what most of the users would be using when they initialise an object as MyClass<char>().

Due to this I am being forced to follow this overloading pattern:

void method(vector<T> elements){

}

void method(string elements){
    method(convertStringToVector(elements));
}

where vector<char> convertStringToVector(string str) is defined as expected.

That is, for each class method I am being forced to add an additional method that overloads for string. I find it an unnecessary overhead, and also sometimes forget to add it.

I will be doing exactly the same things on the string as I would do on the corresponding vector - same methods will be called in both cases, same iteration, etc. Thus, I was wondering if there is a cleaner way to do this, without adding much code overhead. Is there?

like image 605
Gaurang Tandon Avatar asked Mar 04 '23 03:03

Gaurang Tandon


2 Answers

One possible way is to implement your method as a template, whose parameter is not restricted to be either string or vector<char>.

template <typename T>
struct MyClass
{
    template <class C>
    void method(C container);
};

This solves your problem because one implementation is enough for both cases:

template <typename T>
template <class C>
void MyClass<T>::method(C container)
{
    std::cout << "Container has size " << container.size() << '\n';
    std::cout << "First element is " << container[0] << '\n';
}

However, this will work on any container. It's not clear whether this is good (code is generic) or bad (code allows undesirable instantiations).

Imagine what happens when people try to send vector<int> instead of vector<char> to your method by mistake. Because you didn't build your code for this case, it will either display obscure compilation errors, or generate code which silently does the wrong thing at runtime.

like image 174
anatolyg Avatar answered Apr 07 '23 02:04

anatolyg


You can create a class to use as parameter to your methods, which accepts both std::vector<char> and std::string:

class MyString
{
public:
  MyString(const std::vector<char>& v) : vector(v) {}
  MyString(std::vector<char>&& v) : vector(std::move(v)) {}
  MyString(const std::string& s) : vector(convertStringToVector(s)) {}

  std::vector<char> vector;
};

void method(MyString elements)
{
}
like image 40
Boris Rasin Avatar answered Apr 07 '23 01:04

Boris Rasin