Can pure virtual function be Variadic function template? [duplicate] - c++

This question already has answers here:
Can a class member function template be virtual?
(15 answers)
Closed 1 year ago.
Can i write a class like this:
class Base {
template <typename...Args>
virtual double calculate(const Args&...args) = 0;
};
then i want to write derived class like this:
class Derived1 : public Base {
double calculate(int a) {
}
};
class Derived2 : public Base {
double calculate(int a, int c) {
}
};
if this is not possible, is there any methods can achieve this?

No. Virtual functions can not be templates at all. That applies to any template (variadic or not), and all virtual functions - pure or not.
If you think about it, it makes sense. Template is not a function, it is a template by which compiler will make a function when it is called. A virtual function, on the other hand, have to be a real function, which compiler calls through function pointer to achieve polymorphic behavior.

Related

C++ Overload & Override - cannot initialize a parameter of type '' with an rvalue of type '' [duplicate]

This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 5 years ago.
I'm normally a C# guy, and it handles this fine, largely under its handling of "best match" resolving the method to call. I'm trying to do something similar in C++ now, but am getting a compile error. Long story short, it's a combination of method overloading and overriding.
class Bar : public Foo { } //Contents don't really matter here
class Base
{
public:
virtual void Do(Foo* foo) { }
virtual void Do(Bar* bar) { }
};
class Derived : public Base
{
public:
virtual void Do(Bar* bar) { }
}
Foo* foo = new Foo();
Derived* d = new Derived();
d->Do(foo); //cannot initialize a parameter of type 'Bar*' with an rvalue of type 'Foo*'
So, it tries to resolve the method against only the methods in Derived rather than recognizing the base class implements a valid match. Again, C# finds the base method. Can C++ not do this, or am I missing something?
A function in a derived class hides any functions of the same name in a base class (even if you're overriding a virtual function). To unhide the other overloads, use a "using" statement:
class Derived : public Base
{
public:
virtual void Do(Bar* bar) { }
using Base::Do;
};

Difference between overriding and overloading of a function in C++ [duplicate]

This question already has answers here:
Differentiate between function overloading and function overriding
(11 answers)
Overloading and overriding
(12 answers)
Closed 7 years ago.
I am studying c plus plus course in my college and i am unable to differentiate between overriding and overloading of a function can anyone please help me.
Here are two different overloads of foo:
void foo(int);
void foo(char);
Here B::bar is a function override:
class A {
public:
virtual void bar();
};
class B : public A {
public:
void bar() override;
};
overloading means functions with same name having different parameters , it does not really depend whether you are using procedural language or object oriented language you can do overloading. well as far as over riding is concerned it means we are explicitly defining a function that exist in base class in derived class . obviously you need object oriented language to perform over riding as it is done between base and derived classes.
Overloading means declaring more than one function with the same name in the same scope. They must have different parameter types, and the suitable overload is chosen at compile time based on the arguments' static types.
void f(int);
void f(double);
f(42); // selects the "int" overload
f(42.0); // selects the "double" overload
Overriding means that a derived class declares a function that matches a virtual function declared in the base class. Calling the function via a pointer or reference to the base class will select the override at run-time, based on the object's dynamic type.
struct Base {
virtual void f();
};
struct Derived : Base {
void f() override; // overrides Base::f
};
Base * b = new Base; // dynamic type is Base
Base * d = new Derived; // dynamic type is Derived
b->f(); // selects Base::f
d->f(); // selects Derived::f
Overriding means, giving a different definition of an existing function with same parameters,
and overloading means adding a different definition of an existing function with different parameters.
Example:
#include <iostream>
class base{
public:
virtual void show(){std::cout<<"I am base";} //this needs to be virtual to be overridden in derived class
void show(int x){std::cout<<"\nI am overloaded";} //this is overloaded function of the previous one
};
class derived:public base{
public:
void show(){std::cout<<"I am derived";} //the base version of this function is being overridden
};
int main(){
base* b;
derived d;
b=&d;
b->show(); //this will call the derived version
b->show(6); // this will call the base overloaded function
}
Output:
I am derived
I am overloaded

Why use virtual function instead of regular? [duplicate]

This question already has answers here:
Why do we need virtual functions in C++?
(27 answers)
Closed 6 years ago.
In c++, the virtual function in base class can be overridden in derived class.
and a member function where the specific implementation will depend on the type of the object it is called upon, at run-time.
Since virtual function has to be implemented(except for pure virtual)
Can I use regular function in base class and redefine it in derived class?
if yes.
What's the point of using virtual function?
Thanks
You can redefine it but it won't work in a polymorphic way.
so if I have a
class base
{
int foo(){ return 3; }
};
class Der : public base
{
int foo() {return 5;}
};
and then have a function that takes a base
void dostuff(base &b)
{
b.foo(); // This will call base.foo and return 3 no matter what
}
and I call it like this
Der D;
dostuff(D);
Now if I change the base to
class base
{
virtual int foo(){ return 3; }
};
void dostuff(base &b)
{
b.foo(); // This will call the most derived version of foo
//which in this case will return 5
}
so the real answer is if you want to write common code that will call the correct function from the base it needs to be virtual.
Actually, Virtual function is base of object oriented language.
In java, all functions are virtual function.
But in c++, virtual function is slower than regular function.
So if there is no need to function override, you should use regular function instead of virtual function.

Grandparent overloaded function in child [duplicate]

This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
Closed 5 years ago.
I need to understand why C++ don't allow to access Grandparent overloaded functions in Child if any of the overloaded function is declared in Parent. Consider the following example:
class grandparent{
public:
void foo();
void foo(int);
void test();
};
class parent : public grandparent{
public:
void foo();
};
class child : public parent{
public:
child(){
//foo(1); //not accessible
test(); //accessible
}
};
Here, two functions foo() and foo(int) are overloaded functions in Grandparent. But foo(int) is not accessible since foo() is declared in Parent (doesn't matter if it declared is public or private or protected). However, test() is accessible, which is right as per OOP.
I need to know the reason of this behavior.
The reason is method hiding.
When you declare a method with the same name in a derived class, base class methods with that name are hidden. The full signature doesn't matter (i.e. cv-qualifiers or argument list).
If you explicitly want to allow the call, you can use
using grandparent::foo;
inside parent.
Just imagine that a library has this class:
struct Base {
};
In your code you use that class as a base class:
struct Derived : Base {
void f(int);
};
and now you write:
Derived d;
d.f('a');
And now you get the shiny new version 2.0 of that library, and the base class has changed a bit:
struct Base {
void f(char);
}
If overloading applied here, your code would break.

C++: Design, Function template overriding and lack of polymorphism

Have a base class A, and a derived class B which overrides function template Func:
class A
{
A() {...};
~A() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
class B : public A
{
B() {...}
~B() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
(Note that Func is non-virtual, given the lack of support in C++ for templated virtual functions.)
Now have a mainprog API, class M:
class M
{
M(boost::shared_ptr<A> &pInterfaceInput): pInterface(pInterfaceInput)
{}
template <class T>
Evaluate(const String &sInput, T &tResult)
{
pInterface->Func<T>(sInput, tResult);
}
private:
const boost::shared_ptr<A> pInterface;
};
I want the function Evaluate here to support calls to functions on base class A or any of its derived classes (such as B). This class was written with polymorphism in mind before I re-designed class A and B to have templated functions.
Now the problem here is that if I pass a shared pointer of the base type to the derived type then Func of the base class will be called, not the derived class being pointed to.
How do I get around the lack of dynamic polymorphism here?
I've considered making class M a class template on the shared pointer type and having a static_cast in the constructor to ensure this type is of the base class type (A) or of a derived class.
What's the nicest way to do this? I'd prefer not to modify classes A and B to get around this problem but all suggestions are welcome.
Thanks.
Sounds like a double dispatch problem. Perhaps this would be a good place to implement the visitor pattern?
For example, create a class Evaluator, and for each T a subclass ConcreteEvaluator<T>. Give A and B methods that visit the Evaluator. Something like:
class Evaluator
{
virtual void visit_A(A* object);
virtual void visit_B(B* object);
};
template <typename T>
class ConcreteEvaluator : public Evaluator
{
public:
String* input_reference;
T& result_reference;
ConcreteEvaluator(String& input_reference_,T& result_reference_) :
input_reference(input_reference_),
result_reference(result_reference_) {}
virtual void visit_A(A* object) {
object->Func(input_reference,result_reference);
}
virtual void visit_B(B* object) {
object->Func(input_reference,result_reference);
}
}
class A
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_A(this);}
...
}
class B
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_B(this);}
...
}
For each subclass of A, a new method must be added to ConcreteEvaluator, so that this technique works best if A's class hierarchy is stable. And for each subclass of A, it must have an apply_evaluator function defined properly.
On the other hand, this may be total overkill. For about the same amount of work, you could always just pay the price to update M::Evaluate:
class M
{
...
void Evaluate(const String& sInput, T& tResult)
{
// try to downcast to each subclass of A. Be sure to check
// sub-subclasses first
try
{
dynamic_cast<B*>(pInterface.get())->Func(sInput, tResult);
return;
}
catch (std::bad_cast& ) { }
...
// nothing worked. It must really be an A
pInterface->Func(sInput,tResult);
}
...
};
I've show in the question Templatized Virtual function how to use type erasure to get some of the effects of virtual member function. Depending on what you want to do in Func(), you can use the same technique here.