C ++函数重载的后期绑定

时间:2016-05-11 18:36:01

标签: c++ llvm-ir late-binding

假设我有这两个类:

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();
}

众所周知,这段代码将由C ++中的后期绑定处理,由Clang在LLVM IR中实现,如下所示:

 ; ...
  %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)
 ; ...

我的问题是,如果我想创建一个名为check的函数,例如在另一个名称空间中,如下所示:

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

可以将一种后期绑定应用于不同的函数重载吗?

2 个答案:

答案 0 :(得分:4)

不,非成员函数的动态调度目前不是C ++的一部分。

理论上可行,但实现技术并不像虚函数那样简单。有很多提议用这个扩展C ++(关键词:multimethods和multi dispatch),但到目前为止它们还没有产生具体的建议和接受的语言变化。

答案 1 :(得分:-1)

这看起来像是函数指针的工作。

var statuser = 'my user'; // will be available in your callback
chkbox.addEventListener("change", function() {
  searchMap(gblStatus, "Status", statuser, chkbox.checked);
}, false);

它并不完美,但为后期绑定提供了一个很好的解决方法。