2011/10/19 Steckmann, Sven <sven.steckmann@ziehm-eu.com>
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;
}