错误:返回对临时 [-Werror=return-local-addr] 的引用

问题描述 投票:0回答:1

我有一些代码看起来像这样

class Interface
{};

class Contained;

class Container
{
public:
    Container() : m_contained(std::make_shared<Contained>(*this))
    {
    }
    
    std::shared_ptr<Interface> get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }
    
private:
    std::shared_ptr<Contained> m_contained;
};

class Contained final : public Interface
{
public:
    Contained(Container& container) : m_container(container)
    {
    }
    
private:
    Container& m_container;
};

我被要求更改

get_contained
以返回参考,所以我天真地认为这样做

    std::shared_ptr<Interface>& get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }

编译失败

错误:无法将“std::shared_ptr&”类型的非常量左值引用绑定到“std::shared_ptr”类型的右值

所以我添加了

const

    const std::shared_ptr<Interface>& get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }

现在我失败了

错误:返回对临时 [-Werror=return-local-addr] 的引用

然后我又尝试了几个“修复”

class Container
{
public:
    Container()
    {
        m_contained = std::make_shared<Contained>(*this);
    }

    const std::shared_ptr<Interface>& get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }

private:
    std::shared_ptr<Contained> m_contained{};
};

class Container
{
public:
    Container()
    {
        m_contained.reset(new Contained(*this));
    }

    const std::shared_ptr<Interface>& get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }

private:
    std::shared_ptr<Contained> m_contained{};
};

在绝望中

class Container
{
public:
    Container()
    {
        std::shared_ptr<Contained> ptr = std::make_shared<Contained>(*this);
        m_contained = ptr; // also with std::move, but same result
    }

    const std::shared_ptr<Interface>& get_contained()
    {
        return std::static_pointer_cast<Interface>(m_contained);
    }

private:
    std::shared_ptr<Contained> m_contained{};
};

在同一问题上全部失败,无法将左值引用返回到临时值。 我不明白正确初始化的类的成员怎么可能是临时的

c++ shared-ptr
1个回答
0
投票

我认为这不能通过这种方式解决,因为虽然指向派生类的指针也是指向基类的指针(简化的),但保存派生类的

shared_ptr
绝不会通过继承与
shared_ptr
持有基类。

因此没有办法将一个转换为另一个,并且任何伪转换实际上都会创建一个新副本,不幸的是这是暂时的。

如果我可以提出任何建议,以下解决方案可能会起作用:

void get_contained(std::shared_ptr<Interface>& retval)
{
    retval = std::static_pointer_cast<Interface>(m_contained);
}

https://godbolt.org/z/7MoTdxKE6

© www.soinside.com 2019 - 2024. All rights reserved.