2015-04-16 90 views
7

在阅读关于将常量传播包装添加到标准库(文档号N4388)的提议时,我碰到了在纸:如何通过std :: unique_ptr成员调用其他类的const成员函数

#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的(常数)
A ::巴(非const)

我明白为什么会发生这种情况。即使指针是const,它指向的对象也是非const的,所以调用非const成员函数A::bar(这是本文中提议的全部要点,为了避免这种看似尴尬的情况并传播const通过包装)。此外,他们说,为了避免这种情况,一旦可以const_cast的指针m_ptrAB::foo() const,所以它调用所需的A::bar() const

我试过无数组合但坦率地说我不知道​​如何const_castunique_ptr。即,我如何通过m_ptrAB::foo() const执行A::bar() const的“正确”呼叫? (另见代码中的评论,如果它不完全清楚我想要什么)。

+2

'的static_cast (* PTR)。方法()' –

回答

5

您需要常量播所存储的指针,而不是unique_ptr

const_cast<const A*>(m_ptrA.get())->bar(); 
const_cast<const A&>(*m_ptrA).bar(); 
+0

谢谢,这个作品确实如此。出于某种原因,我认为我可以直接在智能指针上使用'const_cast',类似于'shared_ptr'的'static_pointer_cast'。但是你的解决方案可能是唯一的方法。 – vsoftco

+0

@vsoftco智能指针上的const_cast会改变智能指针的常量,但智能指针的'operator - >'和'operator *'不会保留返回对象的常量。这模仿了原始指针的行为。如果你需要const保持指针,你可以使用[this implementation](http://stackoverflow.com/a/21065654/4538344)。 – StenSoft

相关问题