|
Boost Users : |
From: Joerg Faschingbauer (jfasch_at_[hidden])
Date: 2004-02-05 02:39:11
>>>>> "Aaron" == Aaron W LaFramboise <aaronblue6_at_[hidden]> writes:
Aaron> I recently converted a portion of a medium-sized project from
Aaron> loki::Smart_Ptr to boost::shared_ptr (primarily for weak_ptr support),
Aaron> and almost everything worked out of the box, except:
Aaron> boost: template<class Y> explicit shared_ptr <#constructors>(Y * p);
Aaron> loki: SmartPtr(const StoredType& p)
Aaron> In other words, code like this stopped working:
Aaron> some_smart_ptr<int> my_function() {
Aaron> return new int; // error: conversion from `int*' to non-scalar type
Aaron> `boost::shared_ptr<int>'
Aaron> // requested
Aaron> }
Aaron> Even when I adopt the convention to convert the return value to the
Aaron> smart pointer type such as with "return some_smart_ptr<int>(new int)",
Aaron> returning a null pointer as 'zero' doesn't work:
Aaron> some_smart_ptr<int> my_function() {
Aaron> return some_smart_ptr<int>(0); // error: no matching function for
Aaron> call to
Aaron> // `boost::shared_ptr<int>::shared_ptr(int)'
Aaron> }
Aaron> I've worked around this by simply using "return some_smart_ptr<int>();".
Aaron> However, I feel somewhat strongly that this sort of usage is
Aaron> unnecessarily ugly, and confuses the meaning of the code unnecessarily.
Aaron> More importantly, it causes smart pointers to behave differently from
Aaron> ordinary pointers, which is undesirable, as it requires the user (who
Aaron> may not know or care anything about the smart pointer, or even know that
Aaron> it is one, depending on a module's implementation and documentation) to
Aaron> have to learn and use and debug additional semantics.
Aaron> So my question follows. I understand that there are very good reasons
Aaron> for disallowing automatic conversion from a smart pointer, but why
Aaron> disallow automatic conversion to the smart pointer type also? If there
Aaron> are strong reasons for this, would it be reasonable to document this
Aaron> somewhere in the shared_ptr documentation? If not, is this particular
Aaron> aspect of shared_ptr possibly subject to discussion or change in the future?
This is intentional. Consider the following code; using_func() calls
func() with a plain int*, and the int that the pointer points to is on
the stack.
void func(int* p) {
// whatever
}
void using_func() {
int i;
func(&i);
}
Now consider somebody changes func() to take a shared_ptr<> instead of
the plain int*.
void func(shared_ptr<int> p) {
// whatever
}
If automatic conversion was allowed, the code would still compile. The
compiler would generate a temporary shared_ptr<int> before calling
func(). In other words,
void using_func() {
int i;
func(&i);
}
would actually be
void using_func() {
int i;
int* ip = &i;
shared_ptr<int> temporary(ip);
func(temporary);
}
Now this is fatal because temporary's destructor is run at the end of
using_func(). The destructor will see that it is the last instance
that references the pointer, and will delete the int instance - which
is on the stack.
Without automatic conversion, the compiler would barf and using_func()
would have to be fixed.
Joerg
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net