jeudi 16 avril 2015

How to call const other class' member function via a std::unique_ptr member

While reading about a proposal for adding a const-propagating wrapper to the standard library (doc. no. N4388), I bumped into the example given in the paper:



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


which outputs:




B::foo (const)

A::bar (non-const)




I understand why this happens. Even if the pointer is const, the object it points to is non-const, so indeed the non-const member function A::bar is called (this is the whole point of the proposal in the paper, to avoid this seemingly awkward situation and propagate const via a wrapper). Furthermore, they say that to avoid this situation, once can const_cast the pointer m_ptrA in B::foo() const, so it calls the desired A::bar() const.


I tried countless combinations but frankly I don't know how to const_cast the unique_ptr. Namely, how can I enforce in B::foo() const the "right" call to A::bar() const via the m_ptrA? (see also the comment in the code if it's not entirely clear what I want).


Aucun commentaire:

Enregistrer un commentaire