无法返回std :: vector of std :: unique_ptr的std :: vector

时间:2015-07-29 13:01:32

标签: c++ boost vector

我正在为Python编写一个小型C ++模块。在此模块中,我将连接设置为不同的数据库。与其中一个数据库的连接设置如下:

std::unique_ptr<R::Connection> conn = R::connect("localhost", 28015);

设置连接后,我想返回此连接变量。我这样做的方法是使用vectorvariant(因为我可以在向量中返回多个东西 - 数据库连接,一些额外的参数等)。

这就是我定义variantvector类型的方式:

typedef variant<std::unique_ptr<R::Connection>,....connections to other databases> VariantData;
typedef std::vector<VariantData> vector;

最后,这就是我在设置连接后立即返回向量的方法:

return vector{conn, ""};

结果,我得到了一长串错误。但是,此技巧适用于与其他数据库建立连接但不使用unique_ptr的其他客户端。所以,我认为我需要将std::unique_ptr<R::Connection>转换为Connection *或类似的东西,以便能够使用conn变量,就像一般指针一样。

修改

使用以下代码片段:

typedef variant<R::Connection * ,....connections to other databases> VariantData;
typedef std::vector<VariantData> vector;

... function body
... code which does not matter
std::unique_ptr<R::Connection> conn = R::connect("localhost", 28015);
return vector{move(conn),""};

这是我收到的错误消息:

n file included from /usr/include/boost/variant.hpp:17:0,
             from corm.cpp:4:
/usr/include/boost/variant/variant.hpp: In instantiation of ‘typename   boost::enable_if<boost::is_rvalue_reference<T&&> >::type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&&, int, mpl_::false_) [with T = std::unique_ptr<RethinkDB::Connection>; T0_ = mysqlpp::Connection*; T1 = mongo::DBClientBase*; T2 = pqxx::basic_connection<pqxx::connect_direct>*; T3 = sqlite3**; T4 = IBPP::Ptr<IBPP::IDatabase>; T5 = RethinkDB::Connection*; T6 = const char*; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type = void; mpl_::false_ = mpl_::bool_<false>]’:
/usr/include/boost/variant/variant.hpp:1789:62:   required from ‘boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&&, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type*, typename boost::disable_if<boost::is_const<FunctionObj> >::type*) [with T = std::unique_ptr<RethinkDB::Connection>; T0_ = mysqlpp::Connection*; T1 = mongo::DBClientBase*; T2 = pqxx::basic_connection<pqxx::connect_direct>*; T3 = sqlite3**; T4 = IBPP::Ptr<IBPP::IDatabase>; T5 = RethinkDB::Connection*; T6 = const char*; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type = void; typename boost::disable_if<boost::is_const<FunctionObj> >::type = void]’
corm.cpp:94:39:   required from here
/usr/include/boost/variant/variant.hpp:1615:17: error: no matching function for call to ‘boost::variant<mysqlpp::Connection*, mongo::DBClientBase*, pqxx::basic_connection<pqxx::connect_direct>*, sqlite3**, IBPP::Ptr<IBPP::IDatabase>, RethinkDB::Connection*, const char*>::initializer::initialize(void*, boost::remove_reference<std::unique_ptr<RethinkDB::Connection>&>::type)’
             )
             ^
/usr/include/boost/variant/variant.hpp:1615:17: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:33:0,
             from /usr/include/boost/variant.hpp:17,
             from corm.cpp:4:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, 
>::initializer_node::param_T {aka RethinkDB::Connection* const&}’
Makefile:45: recipe for target 'corm.o' failed
make: *** [corm.o] Error 1

修改

这是代码(最小化)

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/variant.hpp>
#include <vector>
#include <memory>
#include <rethinkdb.h>

using namespace boost;
using namespace boost::python;
namespace Ret = RethinkDB;

typedef variant<Ret::Connection *, const char*> VariantData;
typedef std::vector<VariantData> vector;

class ORM{
private:
    int idx;
public:
    ORM(int _idx){
      this->idx = _idx;
    }
    vector Connect(){
        if(this->idx == 8){
            std::unique_ptr<Ret::Connection> conn = Ret::connect(this->host, this->port);
            return vector{std::move(conn), ""};
        }
    }
};


struct variant_to_object:static_visitor<PyObject*>{
   static result_type convert(VariantData const& v){
      return apply_visitor(variant_to_object(), v);
   }
   template<typename T>
   result_type operator () (T const& v) const{
      return incref(object(v).ptr());
   }
};

BOOST_PYTHON_MODULE(corm){   

   class_<vector>("vector").def(vector_indexing_suite<vector, true>());
   to_python_converter<VariantData, variant_to_object>();
   implicitly_convertible<Ret::Connection *, VariantData>();
   implicitly_convertible<const char*, VariantData>();   

   class_<ORM>("ORM",
     init<int>())
     .def("Connect", &ORM::Connect);

}

rethinkdb的客户端来自here

0 个答案:

没有答案