4

Assuming I have these two classes:

class Hello {
    //members
public:
    virtual int doit() {
        return 3;
    }

};

class Wow : public Hello {
    //members
public:
    virtual int doit() {
        return 2;
    }
};

int main(int argc, const char *argv[]) {

    Hello *c = new Wow();

    return c->doit();
}

As we all know, this code will be handled by a late binding in C++, implemented in LLVM IR by Clang like this:

 ; ...
  %7 = bitcast %class.Wow* %5 to %class.Hello*
  store %class.Hello* %7, %class.Hello** %c, align 8
  %8 = load %class.Hello*, %class.Hello** %c, align 8
  %9 = bitcast %class.Hello* %8 to i32 (%class.Hello*)***
  %10 = load i32 (%class.Hello*)**, i32 (%class.Hello*)*** %9, align 8
  %11 = getelementptr inbounds i32 (%class.Hello*)*, i32 (%class.Hello*)** %10, i64 0
  %12 = load i32 (%class.Hello*)*, i32 (%class.Hello*)** %11, align 8
  %13 = call i32 %12(%class.Hello* %8)
 ; ...

My question is, what if I wanna create a function called check for example in another namespace like this:

namespace somewhereelse {
   void check(Hello *c) {
    // Do something
   }
   void check(Wow *c) {
    // Do something else
   }
}

Can a sort of late binding be applied to different function overloads?

NoImaginationGuy
  • 1,795
  • 14
  • 24
  • i'm a tad confused, those overloads due in fact work and the correct version of `check` is called depending on the type of the pointer passed to the function. what are you expecting beyond this? – johnbakers May 11 '16 at 19:46
  • I'll just pass a pointer to the superclass, obviously. i need the runtime to choose the correct overload depending to the pointed object. This is the definition for late binding – NoImaginationGuy May 11 '16 at 19:50
  • i see, wouldn't a single `check` function accepting the base class pointer be able to use `dynamic_cast` to customize behavior for the true underlying type? You'd have to create a new pointer, cast it, and test the result to see if dynamic_cast verified the cast was possible. more work, but I think that's what dynamic_cast is for – johnbakers May 11 '16 at 19:54
  • I can't use RTTI nor exceptions for LLVM policy and code styles, and I was looking for something which doesn't add too much to the code. LLVM coding standards: http://llvm.org/docs/CodingStandards.html – NoImaginationGuy May 11 '16 at 19:57
  • is this doc referring to llvm code or (it looks like) c++ code with custom llvm c++ tools: http://llvm.org/docs/ProgrammersManual.html#isa – johnbakers May 11 '16 at 20:09
  • llvm::isa<> and llvm::dyn_cast<> are implemented by llvm but it's not native. classes that work with those should implement a method, at least that's what I know, and it is pretty annoying – NoImaginationGuy May 11 '16 at 20:22
  • If you want a dynamic type switch, then why wouldn't you use `dynamic_cast`? That's exactly what it's there for. – Kerrek SB May 14 '16 at 13:15
  • I can't use it as I said, because the coding standards of the super project I'm working with (LLVM) does not include RTTI – NoImaginationGuy May 14 '16 at 13:19

2 Answers2

4

No, dynamic dispatch for non-member functions is currently not part of C++.

It is theoretically possible, but the implementation technique is not as straight-forward as for virtual functions. There have been multiple proposals to extend C++ with this (keywords: multimethods and multiple dispatch), but so far they have not resulted in a concrete suggested and accepted language change.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • So much interesting. It should be added to newer C++ standards. I'll probably implement it in my Lang for sure. Maybe a "virtual" attribute to give to parameters, or something like that – NoImaginationGuy May 11 '16 at 19:52
  • Be sure to read the literature on this. It's really a non-trivial problem. – Sebastian Redl May 11 '16 at 22:04
-1

This looks like a job for function pointers.

void (*checkPtr)(Hello*);
...
void check(Hello *c) {
    // Do something
   }
...
checkPtr = &check;

It isn't perfect but makes a good workaround for late binding.