为什么将shared_ptr <t>作为shared_ptr <const t =“”>返回会导致“返回临时”警告的地址?</const> </t>

时间:2010-07-16 17:48:56

标签: c++ visual-studio

class Example
{
    boost::shared_ptr<FilterProvider> filterProvider;
public:
    void RegisterFilter(const boost::shared_ptr<FilterProvider>& toRegister)
    {
        filterProvider = toRegister;
    }
    const boost::shared_ptr<const FilterProvider>& GetFilter() const
    {
        return filterProvider; // Compiler reports "Returning address of local
                               // variable or temporary"
    }
};

我在这里看不到filterProvider的本地或临时内容;我正在返回看起来像是类的成员变量的东西,而不是临时的。 (如果我实际上正在返回一个局部变量或类似的东西,警告会有意义)

具体警告是:

warning C4172: returning address of local variable or temporary.

3 个答案:

答案 0 :(得分:5)

您的共享ptr是使用类型

声明的
boost::shared_ptr<FilterProvider>

你要回来了

boost::shared_ptr<const FilterProvider>

通过const引用。看到区别?

类型不一样,但前者可以转换为后者,编译器会调用转换。转换的结果不是左值,而是临时对象,这意味着您将返回绑定到临时对象的const引用。这是合法的初始化,但临时将在函数返回之前销毁。所以在调用代码中引用将是无效的,这是编译器警告你的内容。

答案 1 :(得分:4)

filterProvider的类型为boost::shared_ptr<FilterProvider>,但您要返回(引用)boost::shared_ptr<const FilterProvider>(请注意const)。就编译器而言,这些类型并不相同。但是,存在隐式转换。这会导致编译器变为临时,而您将返回对该临时的引用,而不是shared_ptr本身。

但是你为什么要首先提出shared_ptr的引用?分发shared_ptr的副本,或者,如果您想阻止修改,请分发const对基础FilterProvider对象的引用。

答案 2 :(得分:2)

filterProvider是指向FilterProvider的共享指针,但GetFilter()会返回对指向const FilterProvider的共享指针的引用。

虽然,例如,int可以被视为const int&,但模板不适用。 Foo<Bar>Foo<const Bar>无任何关联,因此无法视为Foo<const Bar>&

Boost提供从shared_ptr<T>shared_ptr<const T>转换,但此转换涉及创建shared_ptr<const T>类型的新临时对象。

所以这里发生的是你试图从想要返回shared_ptr<FilterProvider>的函数返回shared_ptr<const FilterProvider>&。这将调用显式转换,该转换将创建类型为shared_ptr<const FilterProvider>的新临时对象,然后返回对该引用的引用。因此,您将返回对临时的引用。