我正在尝试在类中调用const
函数,但存在具有相同名称的非const
函数。
注意:我不能只改变名字。
class MyQuestion
{
void fun()
{
cout<<"a";
}
void fun()const
{
cout<<"b";
}
void call()
{
fun();//<how to call fun() const?
}
};
答案 0 :(得分:19)
通过指向const
限定类型的指针调用该函数:
void call()
{
static_cast<const MyQuestion*>(this)->fun();
// ~~~~^
}
void call()
{
const auto* that = this;
//~~^
that->fun();
}
void call()
{
std::as_const(*this).fun();
// ~~~~~~~^
}
使调用函数成为const
- 合格的函数:
void call() const
// ~~~~^
{
fun();
}
答案 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;
}