Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphism with different parameters

Tags:

c++

By any chance is it possible to do polymorphism with the same name of function with different parameters?

For example, I want those three functions to become one.

virtual bool isValid1(const std::string&) = 0;
virtual bool isValid2(const uint32_t&) = 0;
virtual bool isValid3(const int& num) = 0;

In other words, I have a Base A and three Derived A class. I also have Base B that holds a vector of Base A class and a T(template type, could be a string, unit32 or int) argument. When I want to call from Base B the isValid function using the vector and argument (like this: isValid(argument)) I am a bit stuck, since I have to know before if to call isValid1(string), isValid2(uint32) or isValid3(int).

Some piece of the code for those who asked,

template <class T>
class Field
{
public:
    void addValidator(BaseValidator* validator) { m_validator.push_back(validator); }
    void validate() const { m_validator[0].isValid(m_data);}
private:
    std::vector<BaseValidator*> m_validator;
    T m_data;
};
  • I am opting for polymorphism, yet other type of solutions are welcome.
  • Please let me know if the question is too short to understand, so I can rewrite in a different method.
like image 529
Isaac Michaan Avatar asked Mar 25 '19 13:03

Isaac Michaan


2 Answers

You can overload member functions. Even if they are pure virtual and meant to be overriden1:

virtual bool isValid(const std::string&) = 0;
virtual bool isValid(const uint32_t&) = 0;
virtual bool isValid(const int& num) = 0;

Now isValid(argument) is going to do overload resolution and pick the overload to call (via dynamic dispatch). The only potential issue is that the last two overloads may be equally good for certain arguments, so the overloading could be ambiguous. But that really depends on the T in it's called on.


1 - That's exactly what visitation is about, after all.

like image 136
StoryTeller - Unslander Monica Avatar answered Oct 20 '22 19:10

StoryTeller - Unslander Monica


You can indeed use the same member function names in the BaseA class. This is part of overloading and it is completely valid since after the name lookup, ADL will help figure out which function you intend to call.

To be precise, the mangled name of each function you create is dependant upon the function name and function parameters.

struct BaseA
{
    virtual bool isValid(const std::string&) = 0;
    virtual bool isValid(const uint32_t&) = 0;
    virtual bool isValid(const int &num) = 0;
};

The BaseB::validate() const function is a bit sketchy. You might want to pass an std::size_t parameter to access the correct element in the vector.

virtual bool validate(std::size_t elem) const
{
    return vec[elem]->isValid(var);
}

Here's a code example of the final output: https://rextester.com/IHP38905

like image 21
Constantinos Glynos Avatar answered Oct 20 '22 20:10

Constantinos Glynos