Re: Conversion constructor vs. conversion operator Organization: Arcor
"Daniel Kr?gler" <daniel.kruegler@googlemail.com> schrieb im Newsbeitrag news:ipq1vp$dai$1@dont-email.me...
Am 04.05.2011 00:21, schrieb Matthias Hofmann:
"Jeffrey Schwab"<jeff@schwabcenter.com> schrieb im Newsbeitrag
news:fb8a16ec-ccf3-4a2c-b8b3-a99744bd3858@glegroupsg2000goo.googlegroups.com
...
On Monday, May 2, 2011 3:22:39 PM UTC-4, Matthias Hofmann wrote:
I was wondering whether there are any general guidelines as to when a
class
should define a conversion operator rather than conversion constructor?
There is almost never a good reason to provide implicit conversion
operators; always prefer conversion constructors. The only common
exception to this rule is provide a conversion to a boolean type, so
that
objects (e.g., smart pointers) can be used in boolean contexts.
So a conversion constructor should be provided if *explicit* conversion
is
wanted, with the constructor declared as "explicit", while an conversion
operator is meant to enable *implicit* conversion. I think that's a good
rule of thumb and justifies the following member function template
typically
found in smart pointers to enable implicit inheritance based type
conversion:
template<typename T>
class SmartPtr
{
T* m_ptr;
public:
template<typename U>
operator SmartPtr<U>()
{
return SmartPtr<U>( m_ptr );
}
};
A converting constructor is always a non-explicit constructor, see
[class.conv.ctor] p. 1. Your example does not match to what Jeffrey writes
and it turns out that all (new) standard smart pointers provide converting
constructors and no non-explicit conversion functions. In case of smart
pointers it also makes sense to constrain these function template
constructors to reject all those, where the pointer type is not implicitly
convertible to the target pointer.
I was just about to ask you why a conversion constructor should be better
than a non-explicit conversion function when I found out that my example
could not be rewritten according to what Jeffrey writes:
template<typename T>
class SmartPtr
{
T* m_ptr;
public:
SmartPtr( T* ptr = 0 )
: m_ptr( ptr ) {}
// Now using conversion constructor
// instead of conversion operator.
template<typename U>
SmartPtr( const SmartPtr<U>& other )
: m_ptr( other.m_ptr ) {}
};
class Base {};
class Derived : public Base {};
int main()
{
SmartPtr<Derived> x;
// Error: Cannot access private
// member SmartPtr<Derived>::m_ptr.
SmartPtr<Base> y = x;
return 0;
}
I wonder how the new standard smart pointers are supposed to work if they
only use conversion constructors?
--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]