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"
}
};
I don't see what's local or temporary about filterProvider
here; I'm returning what looks like a member variable of the class, not a temporary. (If I was actually returning a local variable or something like that the warning would make sense)
The specific warning is:
warning C4172: returning address of local variable or temporary.
Your shared ptr is declared with type
boost::shared_ptr<FilterProvider>
You are returning
boost::shared_ptr<const FilterProvider>
by const reference. See the difference?
The types are not the same, but the former is convertible to the latter, and the compiler invokes the conversion. The result of the conversion is not an lvalue, but rather a temporary object, meaning that you are returning a const reference bound to a temporary object. This is legal initialization-wise, but the temporary will be destroyed right before the function returns. So in the calling code the reference will be invalid, which is what the compiler is warning you about.
filterProvider
is of type boost::shared_ptr<FilterProvider>
, but you're returning (a reference to) boost::shared_ptr<const FilterProvider>
(note the const
). These types are not the same as far as the compiler is concerned. However, an implicit conversion exists. This causes the compiler to make a temporary instead, and you're returning the reference to that temporary, not to the shared_ptr
itself.
But why are you handing out a reference to a shared_ptr
in the first place? Either hand out a copy of the shared_ptr
, or, if you want to prevent modification, hand out a const
reference to the underlying FilterProvider
object.
filterProvider
is a shared pointer to a FilterProvider
, but GetFilter()
returns a reference to a shared pointer to a const FilterProvider
.
While, for example, an int
can be treated as a const int&
, the same does not hold true for templates. A Foo<Bar>
is not in any way related to a Foo<const Bar>
and so cannot be treated as a Foo<const Bar>&
.
Boost provides a conversion from shared_ptr<T>
to shared_ptr<const T>
, but this conversion involves creating a new temporary object of type shared_ptr<const T>
.
So what is happening here is that you are trying to return a shared_ptr<FilterProvider>
from a function that wants to return a shared_ptr<const FilterProvider>&
. This invokes an explicit conversion which creates a new temporary object of type shared_ptr<const FilterProvider>
and then a reference to that is returned. Therefore, you are returning a reference to a temporary.
精彩评论