如何强制调用const限定函数重载?

时间:2014-12-05 11:59:24

标签: c++ const overloading

我正在尝试在类中调用const函数,但存在具有相同名称的非const函数。

注意:我不能只改变名字。

class MyQuestion
{
 void fun()
 {
   cout<<"a"; 
 }

 void fun()const
 { 
   cout<<"b"; 
 }

 void call()
 {
   fun();//<how to call fun() const?
 }
};

4 个答案:

答案 0 :(得分:19)

选项#1:

通过指向const限定类型的指针调用该函数:

void call()
{
    static_cast<const MyQuestion*>(this)->fun();
    //          ~~~~^
}

void call()
{
    const auto* that = this;
    //~~^
    that->fun();
}

void call()
{
    std::as_const(*this).fun();
    //   ~~~~~~~^
}

选项#2:

使调用函数成为const - 合格的函数:

void call() const
//          ~~~~^
{
    fun();
}

DEMO

答案 1 :(得分:18)

您必须在 const指针上调用该函数。为此,我建议创建一个本地指针变量:

const auto *c = this;
c->fun();   // calls fun() const

fun();      // calls fun()

Live Demo


如果您经常需要,和/或如果您不想使用本地变量,您还可以引入一个私有帮助函数,它返回一个const this指针:

const MyQuestion *const_this() const {
    return this;
}

然后像这样调用fun

const_this()->fun();   // calls fun() const

fun();                 // calls fun()

Live Demo


另一种选择是编写一个make_const函数,它对const指针执行强制转换,而不需要提及类名(它基本上是一个static_cast的const指针。推导类型):

template <typename T>
const T* make_const(T *ptr) {
    return ptr;
}

然后像这样调用fun

make_const(this)->fun();    // calls fun() const

fun();                      // calls fun()

Live Demo


为了争论(我不推荐以下),结合上面的建议,你还可以引入一个扩展到make_const(this)的全局宏: / p>

#define  const_this  make_const(this)

然后像这样调用fun

const_this->fun();   // calls fun() const

fun();               // calls fun()

Live Demo

答案 2 :(得分:4)

我想为已发布的优秀解决方案添加另一种可能的解决方案。

您可以使用带有预期签名的函数指针帮助编译器选择正确的重载:

// Pointer to the version of fun with const
void (MyQuestion::*f)()const = &MyQuestion::fun;
(this->*f)(); // This would call the const fun

请参阅演示here或以下完整代码:

struct MyQuestion
{
    void fun()
    {
        std::cout<<"a"; 
    }

    void fun()const
    { 
        std::cout<<"b"; 
    }

    void call()
    {
        void (MyQuestion::*f)()const = &MyQuestion::fun;
        (this->*f)();
    }
};

为什么这样做?

嗯,f指针的类型是void (MyQuestion::*)()const,它与MyQuestion::foo()const相同,但与MyQuestion::foo()不一样,所以当你取得&MyQuestion::fun的地址时函数f指针{{1}}只能指向const版本。

答案 3 :(得分:3)

如何重载call()本身。以下实施完成了这项工作。我猜这是你想要实现的。

#include <iostream>
using namespace std;

class A
{
public:
    void fun() { cout << "non" << endl; }
    void fun() const { cout << "const" << endl; }

    void call() { fun(); }
    void call() const { fun(); }
};

int main()
{
    A a;
    a.call();

    const A b;
    b.call();
    return 0;
}