I have a base class from which several classes should inherit.
The base class is supposed to be a simple interface, which one inherits for a easy implementation/ for passing data into a library.
However, the parameters of the overridden method vary depending on the implementation (inheritance).
In my concrete case, a class, which should parse a file and the number of the used file paths (and their names) varies depending on the implementation.
Example
This is a boiled-down example to the bare minimum because first I'm not allowed to share my code, and secondly to better illustrates my problem.
class Base
{
public:
Base() = default;
virtual ~Base() = default;
// this should be the interface method
virtual void fn() = 0;
};
class Child1: Base
{
public:
Child1() = default;
virtual ~Child1() = default;
// in this implementation three parameters are needed
virtual void fn(const std::string& file_path_1,
const std::string& file_path_2,
const std::string& file_path_3) override;
};
class Child2: Base
{
public:
Child2() = default;
virtual ~Child2() = default;
// in this implementation only two parameters are needed
virtual void fn(const std::string& file_path_1,
const std::string& file_path_2) override;
};
What I have already tried
I already tried to use Variadic arguments, which could theoretically work. Only the readability suffers and it can't be guaranteed at compile time that the required number of arguments was given.
class Base
{
public:
Base() = default;
virtual ~Base() = default;
// this should be the interface method
virtual void fn(const std::string& file_pats, ...) = 0;
};
I also thought about Variadic Templates, but quickly abandoned this approach due to its complexity/ implementation effort in order to find a more simple solution (but if this is the only viable approach, please tell me).
The Question
Is there a way to have an abstract base class, with a pure virtual method, whose parameters may differ between different implementations?
CodePudding user response:
C-style variadic functions should be avoided in C . Better would be to use variadic template functions, but unfortunately that doesn't really work for virtual functions, see this post for an explanation why.
@AdrianMole and @user17732522 hinted at the right answer: try to find a way to pass a list of things as a single parameter, be that an initializer list or some container like a std::vector
(or a view of a container, for example using C 20's std::span
).
Finally, if the number of arguments really depends on the derived type, then perhaps fn()
should not be a virtual function at all.