如果存在则如何调用C ++对象方法,否则调用全局函数

时间:2018-03-16 18:01:18

标签: c++

我有一个ASSERT宏可以正常工作,因为你会assert工作,除非它调用我自己的全局函数(比如myAssertFunc()),如果断言失败,那么在中止程序之前的一些自定义事项。类似的东西:

#define ASSERT(_c) if (!(_c)) myAssertFunc(#_c)
void myAssertFunc(const char* condition);

(当然没有留下各种细节,但你明白了。)

我希望能够做的是在各种类中定义方法myAssertFunc(),以便在该类的对象的上下文中评估ASSERT()宏时本地方法被调用。所以在某些课程中我会说:

class MyClass {
    void myAssertFunc(const char* condition);
    void run() { ASSERT(isOK); doStuff(); }
};

现在当我在该类的成员方法中调用ASSERT()时,将调用MyClass::myAssertFunc()而不是全局函数。

不幸的是,我在C ++中偶然发现了一个奇怪的范围规则;如果你有一个内部类,那么首先在外部类中匹配符号。如果我有:

class MyClass {
    void myAssertFunc(const char* condition);
    void run() { ASSERT(isOK); doStuff(); }
    class InnerClass {
        void doIt() { ASSERT(canDo); moreStuff(); }
    };
};

一切都会中断,因为在内部类myAssertFunc函数中评估doIt()时,它会莫名其妙地解析为MyClass::myAssertFunc()而不是全局::myAssertFunc()。显然这完全无效,因为我在这里的另一个班级,我无论如何都无法运行该方法!我无法解释为什么那会有用。

无论如何,任何人都可以想到我能做到这一点的方式吗?

如果我有一种方法来编译时检测我当前的类是否有方法我可以这样做:

#define ASSERT(_c) if (!(_c)) if (has_method(myAssertFunc)) myAssertFunc(#_c) else ::myAssertFunc(#_c)

我找到了问题的各种解决方案"如何判断XYZ类是否有方法abc()"但它们都要求你知道XYZ类的名字,我不想:我只想要"当前对象的类"。哦,当然,ASSERT()需要在静态方法中可调用。我开始认为这是不可能的,但也许有人会证明我错了!如果解决方案仅限于相对较新的GCC版本(GCC 6.x及以上版本将是理想的),我感到高兴...如果不能使用Visual Studio或更早版本,我可以。铛/ LLVM。

任何能够为C ++当前名称范围规则WRT内部类提供合理理由的人,我都很好奇。

0 个答案:

没有答案