How to use GCC extension to tell if overloaded method is overridden - c++

It is explained here that gcc gives an extension thats takes a pointer to object and a pointer to virtual method and resolves the dynamic dispatch giving a free function pointer. It is unclear to me how to best do this when the virtual function is overloaded. I have some example code below.
coliru
#include <memory>
#include<iostream>
using namespace std;
struct B{
virtual void f(){cout<<"b\n";}
virtual void f() const {}//this makes things more interesting, can no longer use (F)&B::f, would need extra cast (F)(PTM)&B::f
bool overridesf(){
constexpr void (B::*ptm)()=&B::f;
using PTM = decltype(ptm);
using F = void (*)(B*);
auto thisF = (F)(this->*ptm);
auto notBaseF = (F)(PTM)&B::f;
auto baseF = (F)(B().*ptm);//can simply use (F)&B::f when no overload is present
B b;
//below, all print b when `this` is a B
thisF(this);//c when `this` is a C
thisF(&b);//c when `this` is a C
baseF(this);//b when `this` is a C
baseF(&b);//b when `this` is a C
notBaseF(this);//c when `this` is a C
notBaseF(&b);//c when `this` is a C
//return thisF!=notBaseF; //wrong: is false when this is a c
return thisF!=baseF; //works correctly: true when this is a c
}
};
struct C:B{
void f()override{cout<<"c\n";}
};
int main() {
auto b=make_unique<B>();
cout<<b->overridesf()<<endl;
b=make_unique<C>();
cout<<b->overridesf();
}
I am interested in seeing if a object has overridden the first nonconst f, and I have created a function overridesf to do this. The idea is to do the dynamic dispatch on this to get a function pointer (thisF) and compare this function pointer to what we get if we do dynamic dispatch with an object that is known not to override f (baseF).
In fact, if f is not overloaded, then we can get the baseF function pointer simply with the expression (F)&B::f. However, if f is overloaded, this expression becomes ambiguous and we would have to do (F)(PTM)&B::f, where the PTM cast resolves the overload ambiguity. But (I think) the expression (F)(PTM)&B::f isn't a direct cast of a PMF constant (because of the intermediate cast), so the part about the direct conversion at the end of the linked page doesn't apply and you need an object (in my case B()).
I have two questions. First is there a better way to get baseF? If the interface has many pure virtual functions then it would be annoying to create a derived class which overrides all the pure virtuals (but of course not f) in order to construct an object to get baseF.
Another question is what is going on with notBaseF which is defined by the expression (F)(PTM)&B::f. Presumably this is undefined behavior, but is there an explanation for why the behavior of notBaseF(&b) is determined by the dynamic type of this?

Related

Is there any difference between Namespace::* and traditional *?

class C {
public:
int a;
int f();
};
int C::f() { return 0; }
int main() {
C c {1};
int(C::*pmf)() = &C::f;
// int(*pmf)() = &C::f; -> error can not convert int(*C::f)() to int(*f)().
}
Is there any difference between Namespace::* and * in ram or it is just checked by compiler? Is it syntactic sugar?
Of course: https://isocpp.org/wiki/faq/pointers-to-members
Non-static member functions have a hidden parameter that corresponds to the this pointer. The this pointer points to the instance data for the object.
The functions are physically not interchangable as members have an extra parameter - the object that you call it from. You cannot see it, but the compiler puts it in there. And when that object is missing, compiler obviously complains. This is not like C#, where every function is a member function, and some just happen to be static (fun fact: when passing a C# function to a third party, the object that it is attached to gets passed along with it to allow a valid call later. You may and may not be able to get away with emulating something similar here).

Assign class function pointer to class structure member [duplicate]

I have a C library with a struct like this:
struct A {
void process(){
doProcess();
};
void (*doProcess)(void);
}
Now, I have a class like
class B
{
public:
B(): a(){
a.doProcess = print();
}
void print(){
// do anything
}
private:
A a;
}
This cannot work since print is a member function and has to be called on an object of B.
Thus I tried to use the boost::bind function:
a.doProcess = boost::bind(&A::print, this)
This does not work either.
I also tried to modify the C Library and replace the function pointer definition with a boost::function definition. But then the compiler complains about not finding "" which is included in "boost/function.h".
Is there a (easy/boost) way of assigning a member function to the struct's pointer?
You simply cannot do this. Member functions have an implicit this argument that is a pointer to the object on which the function is being called. A function that does not take a B* as an argument will never manage to run on a specific B instance and a function that does not take this point as its first argument can never have the same signature as a class method. For more details on this problem and an example of a workaround read:
https://isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr
Pay attention to the note at the bottom of the answer on how static member functions can be used in such manner.
Pure C++ projects can use std::function & std::bind to achieve what you are asking about, but a C library used by a C++ project cannot work with these types.

What does operator()() define?

I'm sorry if this question gets reported but I can't seem to easily find a solution online. If I override operator()() what behavior does this define?
The operator() is the function call operator, i.e., you can use an object of the corresponding type as a function object. The second set of parenthesis contains the list of arguments (as usual) which is empty. For example:
struct foo {
int operator()() { return 17; };
};
int main() {
foo f;
return f(); // use object like a function
}
The above example just shows how the operator is declared and called. A realistic use would probably access member variables in the operator. Function object are used in many places in the standard C++ library as customization points. The advantage of using an object rather than a function pointer is that the function object can have data attached to it.

Store pointers to memberfunctions of different classes

I am trying to store pointers to memberfunctions of different Classes in C++. What are the possibilities in C++?
I would like to do this:
class A {
T0 f(T1,T2);
};
class B {
T0 g(T1,T2);
T0 h(T1,T2); //interfaces cant be used since the number of functions per class differs.
};
typedef WHATTOPUTHERE type;
type x;
x = A::f;
x = B::h;
Update: Another Problem is that the code should be continueable like this:
B myB;
myB::x(a,b); //not sure about the syntax, should result in myB::h(a,b) being called
This means that I can not bind at the time I store the pointer, since the instance does not exist (yet).
Function objects to encapsulate your function pointers should work.
boost::function is one option, maybe something like this:
class SomeObj
{
public:
void SetInt(int i);
};
SomeObj myObject;
std::vector<boost::function> memberFuncs;
// in the template arg to boost::bind specify the function type
// _1 here denotes late binding so you can pass whatever value you want when invoked
// you could simply bind a parameter as a variable or literal instead
memberFuncs.push_back(boost::bind<void(int)>(&SomeObj::SetInt, &myObject, _1));
memberFuncs[0](42); // myObject->SetInt(42);
Untested/uncompiled code disclaimer this is just for a general idea.
One possible implementation (using C++11) can easily be done using std::function and a lambda like this:
typedef std::function<void(int)> FunctionType;
SomeClass someClass;
FunctionType func = [&someClass](int argument)
{
someClass.SomeMemberFunction(argument);
};
To have a pointer to Fred::f(char, float) you need this sort of pointer:
int (Fred::*)(char,float)
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
The answer to your particular question is that there is no type that you can add to the typedef and make the code compile. The reason is that member function pointers take a hidden argument of the type of the class form which they are obtained. The type of that hidden argument will be different when you take the address of a member function from A or B.
The next question is whether it makes sense or not from a design perspective, considering that you cannot apply the function pointer A::f to an instance of type B, what is the point of considering member pointers of A and B together?
Now, there are possible workarounds for this particular problem (if it makes sense in your case, but I would first review the design) that involve performing type-erasure on the function pointer to remove the hidden argument and generate an object that is callable with the given set of arguments and return type that is common to all of the member functions. This is already done inside std::function (alternatively boost::function if your compiler does not support C++11), as has been suggested before:
A a_instance;
std::function< T0 (T1,T2) > f( std::bind( &A::f, &a_instance, _1, _2 ) );
T0 r = f( T1(), T2() );
Note that part of the trick is that std::bind binds the member function pointer with the pointer to the instance, filling in the hidden argument, while leaving the other two arguments unbound. At this point, because the result of bind does no longer depend on the type of the first argument, type-erasure can be applied removing A from the type of the resulting object.

Using RTTI to determine inheritance graph in C++?

What, if any, c++ constructs are there for listing the ancestors of a class at runtime?
Basically, I have a class which stores a pointer to any object, including possibly a primitive type (somewhat like boost::any, which I don't want to use because I need to retain ownership of my objects). Internally, this pointer is a void*, but the goal of this class is to wrap the void* with runtime type-safety. The assignment operator is templated, so at assignment time I take the typeid() of the incoming pointer and store it. Then when I cast back later, I can check the typeid() of the cast type against the stored type_info. If it mismatches, the cast will throw an exception.
But there's a problem: It seems I lose polymorphism. Let's say B is a base of D. If I store a pointer to D in my class, then the stored type_info will also be of D. Then later on, I might want to retrieve a B pointer. If I use my class's method to cast to B*, then typeid(B) == typeid(D) fails, and the cast raises an exception, even though D->B conversion is safe. Dynamic_cast<>() doesn't apply here, since I'm operating on a void* and not an ancestor of B or D.
What I would like to be able to do is check is_ancestor(typeid(B), typeid(D)). Is this possible? (And isn't this what dynamic_cast<> is doing behind the scenes?)
If not, then I am thinking of taking a second approach anyway: implement a a class TypeInfo, whose derived classes are templated singletons. I can then store whatever information I like in these classes, and then keep pointers to them in my AnyPointer class. This would allow me to generate/store the ancestor information at compile time in a more accessible way. So failing option #1 (a built-in way of listing ancestors given only information available at runtime), is there a construct/procedure I can use which will allow the ancestor information to be generated and stored automatically at compile-time, preferably without having to explicitly input that "class A derives from B and C; C derives from D" etc.? Once I have this, is there a safe way to actually perform that cast?
I had a similar problem which I solved through exceptions! I wrote an article about that:
Part 1, Part 2 and code
Ok. Following Peter's advise the outline of the idea follows. It relies on the fact that if D derives from B and a pointer to D is thrown, then a catch clause expecting a pointer to B will be activated.
One can then write a class (in my article I've called it any_ptr) whose template constructor accepts a T* and stores a copy of it as a void*. The class implements a mechanism that statically cast the void* to its original type T* and throws the result. A catch clause expecting U* where U = T or U is a base of T will be activated and this strategy is the key to implementing a test as in the original question.
EDIT: (by Matthieu M. for answers are best self-contained, please refer to Dr Dobbs for the full answer)
class any_ptr {
void* ptr_;
void (*thr_)(void*);
template <typename T>
static void thrower(void* ptr) { throw static_cast<T*>(ptr); }
public:
template <typename T>
any_ptr(T* ptr) : ptr_(ptr), thr_(&thrower<T>) {}
template <typename U>
U* cast() const {
try { thr_(ptr_); }
catch (U* ptr) { return ptr; }
catch (...) {}
return 0;
}
};
The information is (often) there within the implementation. There's no standard C++ way to access it though, it's not exposed. If you're willing to tie yourself to specific implementations or sets of implementations you can play a dirty game to find the information still.
An example for gcc, using the Itanium ABI is:
#include <cassert>
#include <typeinfo>
#include <cxxabi.h>
#include <iostream>
bool is_ancestor(const std::type_info& a, const std::type_info& b);
namespace {
bool walk_tree(const __cxxabiv1::__si_class_type_info *si, const std::type_info& a) {
return si->__base_type == &a ? true : is_ancestor(a, *si->__base_type);
}
bool walk_tree(const __cxxabiv1::__vmi_class_type_info *mi, const std::type_info& a) {
for (unsigned int i = 0; i < mi->__base_count; ++i) {
if (is_ancestor(a, *mi->__base_info[i].__base_type))
return true;
}
return false;
}
}
bool is_ancestor(const std::type_info& a, const std::type_info& b) {
if (a==b)
return true;
const __cxxabiv1::__si_class_type_info *si = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&b);
if (si)
return walk_tree(si, a);
const __cxxabiv1::__vmi_class_type_info *mi = dynamic_cast<const __cxxabiv1::__vmi_class_type_info*>(&b);
if (mi)
return walk_tree(mi, a);
return false;
}
struct foo {};
struct bar : foo {};
struct baz {};
struct crazy : virtual foo, virtual bar, virtual baz {};
int main() {
std::cout << is_ancestor(typeid(foo), typeid(bar)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(baz)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(int)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(crazy)) << "\n";
}
Where I cast the type_info to the real type that's used internally and then recursively used that to walk the inheritance tree.
I wouldn't recommend doing this in real code, but as an exercise in implementation details it's not impossible.
First, what you are asking for cannot be implemented just on top of type_info.
In C++, for a cast to occur from one object to another, you need more than blindly assuming a type can be used as another, you also need to adjust the pointer, because of multi-inheritance (compile-time offset) and virtual inheritance (runtime offset).
The only way to safely cast a value from a type into another, is to use static_cast (works for single or multi-inheritance) and dynamic_cast (also works for virtual inheritance and actually checks the runtime values).
Unfortunately, this is actually incompatible with type erasure (the old template-virtual incompatibility).
If you limit yourself to non-virtual inheritance, I think it should be possible to achieve this by storing the offsets of conversions to various bases in some Configuration data (the singletons you are talking about).
For virtual inheritance, I can only think of a map of pairs of type_info to a void* (*caster)(void*).
And all this requires enumerating the possible casts manually :(
It is not possible using std::type_info since it does not provide a way to query inheritance information or to convert a std::type_info object to its corresponding type so that you could do the cast.
If you do have a list of all possible types you need to store in your any objects use boost::variant and its visitor.
While I can't think of any way to implement option #1, option #2 should be feasible if you can generate a compile-time list of the classes you would like to use. Filter this type list with boost::MPL and the is_base_of metafunction to get a list of valid-cast typeids, which can be compared to the saved typeid.