C++: Test if class instance implements a virtual method [duplicate] - c++

I want to be able to tell at run-time if an instance of a class implements a virtual function. For example:
struct Base
{
virtual void func(int x) { <default behavior here> }
virtual void func2(int x) { <default behavior here> }
};
struct Deriv : Base
{
virtual void func(int x) override { <new behavior here> }
};
int main()
{
Base *d = new Deriv;
if(implements<Base::func(int)>(d)) // This should evaluate true
{}
if(implements<Base::func2(int)>(d)) // This should evaluate false
{}
}
I have seen this but it's dated and there might be a something that c++11/14 has to say now:
Ways to detect whether a C++ virtual function has been redefined in a derived class

The short answer is: No. And certainly not in a portable manner.
The longer answer: actually, the very goal of polymorphism is to make it indistinguishable to the user where the functionality comes from.
Even if the developer does not write code, the compiler might still generate a dedicated version of the function for the derived class (for better optimization). This would throw off even non-portable implementations that would inspect the virtual tables...
An alternative route, however, would be to throw off C++ automatic run-time polymorphism and instead provide an ad-hoc implementation. If for example you were to provide your own virtual table/pointer mechanism, then you would have more control:
struct VirtualTable {
typedef void (*FuncType)(void*, int);
typedef void (*Func2Type)(void*, int);
FuncType func;
Func2Type func2;
};
and you could check whether the function pointer is, or is not, equal to the default.

What comes to my mind right now is to have a special "counter" variable, which will take its value based on the implementation and zero if the base-class function is called. I think that this sounds a bit obsolete style though and try to find a better solution in a moment. See the example for now:
struct Base
{
virtual void func(int x, int& implemented) {implemented = 0;}
};
struct Deriv : Base
{
virtual void func(int x, int& implemented) override {implemented = 1;}
};
If the functions are void as in your example, you also can use "return codes" - just return implemented value back.

Related

How to check if a function has an implementation at run time in C++11? [duplicate]

I want to be able to tell at run-time if an instance of a class implements a virtual function. For example:
struct Base
{
virtual void func(int x) { <default behavior here> }
virtual void func2(int x) { <default behavior here> }
};
struct Deriv : Base
{
virtual void func(int x) override { <new behavior here> }
};
int main()
{
Base *d = new Deriv;
if(implements<Base::func(int)>(d)) // This should evaluate true
{}
if(implements<Base::func2(int)>(d)) // This should evaluate false
{}
}
I have seen this but it's dated and there might be a something that c++11/14 has to say now:
Ways to detect whether a C++ virtual function has been redefined in a derived class
The short answer is: No. And certainly not in a portable manner.
The longer answer: actually, the very goal of polymorphism is to make it indistinguishable to the user where the functionality comes from.
Even if the developer does not write code, the compiler might still generate a dedicated version of the function for the derived class (for better optimization). This would throw off even non-portable implementations that would inspect the virtual tables...
An alternative route, however, would be to throw off C++ automatic run-time polymorphism and instead provide an ad-hoc implementation. If for example you were to provide your own virtual table/pointer mechanism, then you would have more control:
struct VirtualTable {
typedef void (*FuncType)(void*, int);
typedef void (*Func2Type)(void*, int);
FuncType func;
Func2Type func2;
};
and you could check whether the function pointer is, or is not, equal to the default.
What comes to my mind right now is to have a special "counter" variable, which will take its value based on the implementation and zero if the base-class function is called. I think that this sounds a bit obsolete style though and try to find a better solution in a moment. See the example for now:
struct Base
{
virtual void func(int x, int& implemented) {implemented = 0;}
};
struct Deriv : Base
{
virtual void func(int x, int& implemented) override {implemented = 1;}
};
If the functions are void as in your example, you also can use "return codes" - just return implemented value back.

static_assert : a certain function in Derive "must" hides Base's class function

I face a strange rare problem that I want to hide a Base class's function B::f1(int).
class B{
public: void f1(int){}
public: void f1(float){}
};
class C : public B{
public: void f1(int){
//static_assert(ASSERT_that_thisFunctionHidParentFunction,"");
//some rare ugly hacky stuff
}
public: void f1(char){
//static_assert(!ASSERT_that_thisFunctionHidParentFunction,"");
}
};
Everything works fine ; I just worry about maintainability.
I wish to make sure that a function C::f1(int) always hides B::f1(int).
If B::f1(int) happen to change signature in the future (e.g. to B::f1(int,int)),
I want some compile error to notify programmers that C::f1(int) should be changed to C::f1(int,int) as well.
In real world, my problematic function f1 doesn't have overload.
But for educational purpose, I wish to know how to solve it if there are overload too. (i.e. optional)
I love a cute solution like ASSERT_that_thisFunctionHidParentFunction in my code comment.
I don't mind MACRO.
My poor solution
I tried to typedef to force compile error, but it doesn't assert-fail in some case (MCVE-coliru), because int is automatically casted to B::f1(float).
class B{
public: void f1(int,int){}
public: void f1(float){}
};
class C : public B{
public: void f1(int){
using XXX=decltype(std::declval<B>().f1(std::declval<int>()));
//static_assert(ASSERT_that_thisFunctionHidParentFunction,"");
}
public: void f1(char){
//static_assert(!ASSERT_that_thisFunctionHidParentFunction,"");
}
};
int main() {
return 0;
}
You could check that the function pointers are different.
With MSVC 2019 and Clang 8 this worked for me, however GCC rejected it as "not a constant expression", so might need something different or a a runtime assert there. Not sure which is right in regards to the standard.
class B {
public:
void f1(int) {}
void f2(int) {}
void f3(int) {}
void f1(float) {}
};
class C : public B {
public:
void f1(int) {}
void f1(char) {}
void f3(int) {}
};
static_assert(&B::f1 != &C::f1); // Won't work because of the overloading, can static_cast to get the overload you want
static_assert(static_cast<void(B:: *)(int)>(&B::f1) != static_cast<void(C:: *)(int)>(&C::f1));
static_assert(static_cast<void(B:: *)(int)>(&B::f2) != static_cast<void(C:: *)(int)>(&C::f2)); // static assertion failed
static_assert(&B::f3 != &C::f3); // passes, no static_cast as not overloaded
Be very careful with hiding a member function in this way, as the base class is public and the method is not virtual. It can easily be cast and then the derived function is not called.
C *c = ...;
B *b = c; // Implicit
b->f1(5); // Calls B::f1, not C::f1
If possible it may be best to make the inheritance protected or private to avoid accidental casting.
The way I understand your question, it seems that you want to make sure that several implementation classes comply with a certain non-virtual concept.
template <typename Candidate>
struct ShipConcept
{
constexpr ShipConcept()
{
using ProtoFoo = void (Candidate::*)(int);
(void)static_cast<ProtoFoo>(&Candidate::foo);
// Other tests ...
}
};
struct Ship_A
: private ShipConcept<Ship_A>
{
Ship_A()
{
}
void foo(int, int);
void foo(float);
void foo(int); // (1)
};
You'll get compile-time error if line (1) isn't there.

Is there a way to detect if a function is overridden?

Suppose we have an abstract Base class that is inherited:
class Base
{
protected:
Base() {}
virtual ~Base() {}
virtual void on_event_foo(int) {}
virtual void on_event_bar(int) {}
};
struct Concrete : public Base
{
virtual void on_event_foo(int value) {/*do some stuff with #value*/}
};
Is it a way to know (at compile time would be the best) the virtual functions from Base that was overridden (with some code in constructor, or with a special pattern)?
My purpose is to implement a wrapper for a library that use some callbacks ; and if I can do check the overriden functions, I will create only the callbacks the user wants.
I want the user can choose the function he wants to override. Then in my code, I will create callbacks only for the overridden functions. The pure virtual functions are not a solution, because they cannot permit to create a concrete class without overriding all of them.
In the constructor of Base, for now, I connect a lot of static callback functions of Base within a C API. In those functions, I call the corresponding member function. For example, the callback function is static Base::EventFoo(/* ... */) that calls inside object->on_event_foo(/* .. */). This is because I cannot give a member function as a callback to a C library.
But creating too much callbacks make my wrapper slower. So, I want to connect only the callback that the user wants, ie knowing the functions there are overriden by him.
Disclaimer: I've been notified that this behavior is unspecified since it relies on comparing virtual member function pointers:
[expr.eq] ... if either is a pointer to a virtual member function, the result is unspecified.
Wording is present in all C++ standards (that I could check). Your results may vary.
If you are willing to change a few things, you can use the curiously recurring template pattern to determine if the function is overridden
#include <iostream>
template <class Derived>
struct Base
{
virtual void on_event() {}
void raise_event()
{
if (&Derived::on_event == &Base::on_event)
std::cout << "not overridden" << std::endl;
else
std::cout << "overridden" << std::endl;
}
};
struct Concrete1 : Base<Concrete1>
{
virtual void on_event() override {}
};
struct Concrete2 : Base<Concrete2>
{
// no override
};
int main()
{
Concrete1 c1;
Concrete2 c2;
c1.raise_event(); // prints overridden
c2.raise_event(); // prints not overridden
return 0;
}
The statement &Derived::on_event == &Base::on_event should be resolved at compile-time (if that's what you're worried about) and the if can be optimized away.
Though I agree with others' opinions that this seems like a poor pattern. It would be much simpler to have the base class have empty event handlers like you already have.
Don't use virtual methods at all. If all you want is given some concrete type, Concrete, to hook it up to a bunch of callbacks based on the presence of member functions then we can use templates.
For a given type and function name, we can determine if &T::func exists at compile time. If it does, we add that callback. So we end up with a whole bunch of things like:
template <class T>
void setup_cbs(T& object) {
T* ptr_to_object = ...; // store somewhere
static_if<has_on_event_foo<T>>(
[](auto ptr){
add_event_foo_callback(ptr, [](void* p, int i) {
using U = decltype(ptr);
static_cast<U>(p)->on_event_foo(i);
})
}),
[](auto ){}
)(ptr_to_object);
I'm assuming the callback adder takes a pointer and a callback. You will separately have to figure out how to store the pointers, but that seems easier.
With modern c++ you can do this:
if constexpr (!std::is_same_v<decltype(&Derived::foo), decltype(&Base::foo)>) {
std::cout << "overrided" << std::endl;
}
You may want to define a macro like this:
#define OVERRIDED(B, D, name) !std::is_same_v<decltype(&B::name), decltype(&D::name)>

Can I tell if a C++ virtual function is implemented

I want to be able to tell at run-time if an instance of a class implements a virtual function. For example:
struct Base
{
virtual void func(int x) { <default behavior here> }
virtual void func2(int x) { <default behavior here> }
};
struct Deriv : Base
{
virtual void func(int x) override { <new behavior here> }
};
int main()
{
Base *d = new Deriv;
if(implements<Base::func(int)>(d)) // This should evaluate true
{}
if(implements<Base::func2(int)>(d)) // This should evaluate false
{}
}
I have seen this but it's dated and there might be a something that c++11/14 has to say now:
Ways to detect whether a C++ virtual function has been redefined in a derived class
The short answer is: No. And certainly not in a portable manner.
The longer answer: actually, the very goal of polymorphism is to make it indistinguishable to the user where the functionality comes from.
Even if the developer does not write code, the compiler might still generate a dedicated version of the function for the derived class (for better optimization). This would throw off even non-portable implementations that would inspect the virtual tables...
An alternative route, however, would be to throw off C++ automatic run-time polymorphism and instead provide an ad-hoc implementation. If for example you were to provide your own virtual table/pointer mechanism, then you would have more control:
struct VirtualTable {
typedef void (*FuncType)(void*, int);
typedef void (*Func2Type)(void*, int);
FuncType func;
Func2Type func2;
};
and you could check whether the function pointer is, or is not, equal to the default.
What comes to my mind right now is to have a special "counter" variable, which will take its value based on the implementation and zero if the base-class function is called. I think that this sounds a bit obsolete style though and try to find a better solution in a moment. See the example for now:
struct Base
{
virtual void func(int x, int& implemented) {implemented = 0;}
};
struct Deriv : Base
{
virtual void func(int x, int& implemented) override {implemented = 1;}
};
If the functions are void as in your example, you also can use "return codes" - just return implemented value back.

C++ idiom for base class abstract methods without dynamic dispatch overhead?

In C++, is there any way to have an "abstract" base class method (i.e., declared and callable from the base class, but implemented in subclasses) without declaring the method as virtual?
This question, of course, only applies to cases where polymorphism isn't needed (pointers/references to base types never used). Consider the following:
#define NO_OPT asm volatile (""); // to prevent some compiler optimization
template<typename DerivedType>
void doSomething(DerivedType& d) { d.foo(); }
namespace test1 {
struct Base {
inline void foo()
{
// ... do common stuff pre-call ...
foo_impl();
// ... do common stuff post-call ...
}
virtual void foo_impl() = 0; // the abstract method
};
struct D1 : public Base { virtual void foo_impl() final { NO_OPT } };
struct D2 : public Base { virtual void foo_impl() final { NO_OPT } };
// Then the usage of D1, D2, ..., DN, could be as follows:
void go() {
D1 d1; doSomething(d1);
D2 d2; doSomething(d2);
for ( long i=0; i < 5000000000; i++ ) {
// this loop takes [9] seconds
doSomething(d2);
}
}
}
Note that polymorphism is not needed in this case, and that there are plenty of optimization opportunities for the compiler.
However, I benchmarked this code in the latest g++ (4.8.2) and clang (3.4) with -O3 optimizations enabled, including link-time (LTO), and it was significantly slower than the following alternative implementation (using templates instead of virtual method):
namespace test2 {
template<typename DerivedType>
struct Base : public DerivedType // inheritance in reverse
{
inline void foo()
{
// ... do common stuff pre-call ...
DerivedType::foo_impl();
// ... do common stuff post-call ...
}
};
struct D1 { void foo_impl() { NO_OPT } };
struct D2 { void foo_impl() { NO_OPT } };
void go() {
Base<D1> d1; doSomething(d1);
Base<D2> d2; doSomething(d2);
for ( long i=0; i < 5000000000; i++ ) {
// this loop takes [3] seconds
doSomething(d2);
}
}
}
g++ and clang were remarkably consistent, each compiling optimized code that took 9 seconds to execute the test1 loop, but only 3 seconds to execute the test2 loop. So even though the test1 logic has no need for dynamic dispatch as all calls should be able to be resolved at compile time, it is still significantly slower.
So to restate my question: When polymorphism isn't needed, Is there a way to achieve this "abstract method" behavior using the convenient straight-forward class inheritance (like in test1), but without the performance penalty of virtual functions (as achieved in test2)?
Why should explicitly invoking runtime support for a situation you don't have and don't want to have be considered straightforward? That'll confuse humans, too. Templates are the perfect tool for this job.
You want a common interface. Given your example template implementation, you don't even need any obvious relation between the types that have it, just that they do have it.
The classic CRTP way is
template<class d>
struct b {
void foo() { bark(); static_cast<d*>(this)->foo_impl(); bite(); }
};
struct d1 : b<d1> { void foo_impl() { fuzzbang("d1"); } };
struct d2 : b<d2> { void foo_impl() { fizzbuzz("d2"); } };
which people will have seen before, it's idiomatic as requested, but your
class m1 { protected: void foo_impl() { f1("1"); } };
class m2 { protected: void foo_impl() { f2("2"); } };
template<class m>
struct i : private m { void foo() { bark(); m::foo_impl(); bite(); } };
has a lot to recommend it too: there's no casting necessary, and the intent is as clear.
I don't think you can legitimately compare optimizer results on code with embedded volatile accesses with results on similar code without them. Try the two implementations in your actual code. Performance for anything you're doing five billion times is almost certain to be dominated by cache effects not instruction count anyway.
If a function has a polymorphic value (a reference or pointer to a polymorphic type), and it calls a virtual function through that variable, the compiler must assume that this could be that class or any class derived from it. And since polymorphism doesn't allow the compiler to know whether there are classes derived from it, it must use a virtual dispatch to call the function.
There is only one way to avoid the use of virtual dispatch on calling a virtual function via a polymorphic value: to call the specific type's function directly, exactly as you did in your case #2.
Where you put this call is up to you. You could put the call into foo, you could have a derived_foo alternate function that people use to call the derived-class version, etc. However you want to do it, you must ultimately call the virtual function in a different way. Which requires using a different codepath.
It is possible that, if provided with a polymorphic variable of a final class, a compiler could optimize all virtual calls into that variable into non-virtual dispatches. However, that is not required behavior by the standard. Each compiler may or may not implement that optimization, so unless it becomes widespread, you can't count on it.
This question seems very much like an XY problem. You're trying to solve some problem, and you settled on a base class with a virtual function, with a derived class that you'll always be using. This problem is best solved via the CRTP, which doesn't use virtual functions at all.
If you do not need dynamic polymorphism then do not use keyword virtual in your code:
#define NO_OPT asm volatile (""); // to prevent some compiler optimization
template<typename T>
void doSomething(T& d) { d.foo(); }
namespace test1
{
struct Base
{
protected:
void prior() {}
void after() {}
};
struct D1
:public Base
{
void foo()
{
prior();
NO_OPT
after();
}
};
struct D2
:public Base
{
void foo()
{
prior();
NO_OPT
after();
}
};
void go() {
D1 d1; doSomething(d1);
D2 d2; doSomething(d2);
for ( long i=0; i < 5000000000; i++ ) {
doSomething(d2);
}
}
}