在阅读一个向标准库添加常量传播包装器的提案时(文档编号:N4388),我遇到了论文中给出的例子:
#include <memory>
#include <iostream>
struct A
{
void bar() const
{
std::cout << "A::bar (const)" << std::endl;
}
void bar()
{
std::cout << "A::bar (non-const)" << std::endl;
}
};
struct B
{
B() : m_ptrA(std::make_unique<A>()) {}
void foo() const
{
std::cout << "B::foo (const)" << std::endl;
m_ptrA->bar(); // calls A::bar() (non-const)
// const_cast<const std::unique_ptr<A>>(m_ptrA)->bar(); // how to call the A::bar() const?
}
void foo()
{
std::cout << "B::foo (non-const)" << std::endl;
m_ptrA->bar();
}
std::unique_ptr<A> m_ptrA;
};
int main()
{
const B const_b;
const_b.foo();
}
输出如下:
B::foo (const)
A::bar (non-const)
我理解为什么会出现这种情况。即使指针是const
,它所指向的对象仍然是非const
的,因此实际上调用了非const
成员函数A::bar
(这就是论文提议的整个目的,通过包装器传播const
来避免这种看似尴尬的情况)。此外,他们说为了避免这种情况,可以在B::foo() const
中对指针m_ptrA
进行const_cast
,以调用所需的A::bar() const
。
我尝试了无数组合,但老实说我不知道如何const_cast
unique_ptr
。也就是说,在B::foo() const
中,我该如何通过m_ptrA
强制执行对A::bar() const
的“正确”调用?(如果不完全清楚我的意思,请参见代码中的注释。)
static_cast<const Type&>(*ptr).method()
- Tavian Barnes