Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve conflict between boost::shared_ptr and using std::shared_ptr?

Tags:

c++

c++11

boost

If I change from boost::shared_ptr to std::shared_ptr in this code snippet, I will get linker error.

#include <iostream>
#include <sstream>
#include <iterator>
#include <cctype>
#include <cmath>

#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>

#include <functional>
#include <utility>
#include <numeric>

#include <boost/assign.hpp>
#include <boost/assign/std/vector.hpp>

#include <boost/algorithm/string.hpp>

#include <boost/test/included/unit_test.hpp>
#include <boost/test/included/unit_test_framework.hpp>
#include <boost/bind.hpp>

//using namespace std;
//using namespace boost;

using std::string;
using std::ostringstream;
using namespace boost::assign;
using namespace boost::unit_test;

template<typename T> string to_string( T data ) { ostringstream ost; ost << data; return ost.str(); }

class TwoStringMasks {
public:
    string shortestCommon( string s1, string s2 ) {
        //if( s1.find( "*" ) != 0 ||
        return "";
    }
};

class two_string_masks_test {
public:
    void test_case_one() {
        string str = "TOPCODER*";
        BOOST_CHECK_EQUAL( str.find( "*" ), str.length() - 2 );
    }
};

test_suite* init_unit_test_suite( int argc, char* argv[] ) {
    boost::shared_ptr<two_string_masks_test> tester( new two_string_masks_test );
    framework::master_test_suite().add(  
        BOOST_TEST_CASE( boost::bind( &two_string_masks_test::test_case_one, tester ) ) ); 
    return 0;
}

Error:

Error   12  error C2784: 'T *boost::get_pointer(T *)' : could not deduce template argument for 'T *' from 'std::tr1::shared_ptr<_Ty>'   c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   10  error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   11  error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   8   error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   9   error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   6   error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   7   error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   13  error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>'   c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   14  error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>'   c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   2   error C2784: 'optional<T>::pointer_type boost::get_pointer(boost::optional<T> &)' : could not deduce template argument for 'boost::optional<T> &' from 'std::tr1::shared_ptr<_Ty>'  c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   3   error C2784: 'optional<T>::pointer_type boost::get_pointer(boost::optional<T> &)' : could not deduce template argument for 'boost::optional<T> &' from 'std::tr1::shared_ptr<_Ty>'  c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   4   error C2784: 'optional<T>::pointer_const_type boost::get_pointer(const boost::optional<T> &)' : could not deduce template argument for 'const boost::optional<T> &' from 'std::tr1::shared_ptr<_Ty>'    c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report
Error   5   error C2784: 'optional<T>::pointer_const_type boost::get_pointer(const boost::optional<T> &)' : could not deduce template argument for 'const boost::optional<T> &' from 'std::tr1::shared_ptr<_Ty>'    c:\program files\boost\boost_1_44\boost\bind\mem_fn_template.hpp    40  1   NET Report

What did I do wrong? I guessed there was a conflict between std namespace and boost namespace, but I don't know how to fix it? Any idea?

Thanks,
Chan

like image 958
Chan Avatar asked Jan 13 '11 16:01

Chan


4 Answers

It looks like you need to add an overload of get_pointer to use std::shared_ptr with boost::bind.

namespace boost { 
  template<class T> const T* get_pointer(const std::shared_ptr<T>& ptr) 
  {
    return ptr.get();
  }

  template<class T> T* get_pointer(std::shared_ptr<T>& ptr)
  {
    return ptr.get();
  }
}

I'd assume that this is already working if you use std::bind instead. Or use tester.get() in the bind.

like image 78
ltjax Avatar answered Nov 01 '22 13:11

ltjax


Boost and TR1 shared pointers are separate implementations and are not compatible - pick one or the other and use it exclusively.

like image 38
bdonlan Avatar answered Nov 01 '22 12:11

bdonlan


boost::bind does not know what to do with tr1::shared_ptr it knows how to handle boost::shared_ptr.

You could try tr1::bind which probably works with tr1::shared_ptr.

The only issue then is whether that will work in BOOST_TEST_CASE. If it just expects a "runnable" then a tr1::function is just as "runnable" as a boost one.

like image 3
CashCow Avatar answered Nov 01 '22 12:11

CashCow


Have you noticed that you do not explicitly include the < memory > header (nor < boost/shared_ptr.hpp > for that matter)?

If you provided some more info, it'd be easier to help.

  1. What compiler are you using?
  2. Are you expecting to use tr1 from your compiler of from boost?
  3. Do you want to access shared_ptr as std::tr1::shared_ptr or simply std::shared_ptr?
like image 1
broc Avatar answered Nov 01 '22 11:11

broc