Boost logo

Boost Users :

Subject: Re: [Boost-users] [shared_ptr] implicit conversion to bool problem
From: Krzysztof Czainski (1czajnik_at_[hidden])
Date: 2011-10-19 07:25:42


2011/10/19 Steckmann, Sven <sven.steckmann_at_[hidden]>

> Dear list,
>
> I have a problem with the implicit conversion to bool in the shared_ptr
> class.
>
> I want to use operator overloading for an easy to use interface. I have
> 2 Instances of a class with a common
> Interface and I want to define an operator-class (OpAnd of type K) which
> can handle the operator.
>
> By compiling this little test below, I got:
> g++ -I/home/steckmann/proj/libs/boost -O0 -g3 -Wall -c
> -fmessage-length=0 -MMD -MP -MF"test.d" -MT"test.d" -o "test.o"
> "../test.cpp"
> ../test.cpp: In function 'int main()':
> ../test.cpp:49: error: ambiguous overload for 'operator&&' in 'a && b'
> ../test.cpp:49: note: candidates are: operator&&(bool, bool) <built-in>
> ../test.cpp:40: note: boost::shared_ptr<K>
> operator&&(boost::shared_ptr<K>, boost::shared_ptr<K>)
>
> This is quite clear to me, but how can I avoid this without touching the
> shared_ptr?
>
> Thanks for any comments,
> Sven
>
> #include <boost/shared_ptr.hpp>
>
> using namespace boost;
>
> class K
> {
> public:
> virtual bool value() = 0;
> };
>
> class Value
> :public K
> {
> public:
> Value( bool i )
> : var( i ) {}
>
> bool value() { return var; }
>
> bool var;
> };
>
> class OpAnd
> : public K
> {
> public:
> OpAnd( boost::shared_ptr<K> l, boost::shared_ptr<K> r )
> :l(l), r(r)
> {}
>
> bool value()
> {
> return l->value() && r->value();
> }
>
> boost::shared_ptr<K> l;
> boost::shared_ptr<K> r;
> };
>
> boost::shared_ptr<K> operator&&( boost::shared_ptr<K> l,
> boost::shared_ptr<K> r)
> {
> return shared_ptr<K>( new OpAnd(l, r ) );
> }
>

I'd really rethink the design ;-) that said, let's see: looks like
shared_ptr<Value> is convertible to shared_ptr<K> and to some
unspecified_bool_type. So what you need is a better matching template for
operator &&, somthing like [warning: not tested]:

template < class T >
boost::shared_ptr<K> operator&&( boost::shared_ptr<T> l,
boost::shared_ptr<T> r )
{
  return shared_ptr<K>( new OpAnd(l,r) );
}

Also, you might want to enable_if that only for Ts that are derived from K.

Hope this helps

Regards
Kris

>
> int main()
> {
> boost::shared_ptr<Value> a( new Value(true) );
> boost::shared_ptr<Value> b( new Value(false) );
> boost::shared_ptr<K> c = a && b;
>
> // Now use c here for some stuff
> c->value(); // returns false
>
> b->var = true;
>
> c->value(); // returns true
>
> return 0;
> }
>



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