我正在为Python编写一个小型C ++模块。在此模块中,我将连接设置为不同的数据库。与其中一个数据库的连接设置如下:
std::unique_ptr<R::Connection> conn = R::connect("localhost", 28015);
设置连接后,我想返回此连接变量。我这样做的方法是使用vector
和variant
(因为我可以在向量中返回多个东西 - 数据库连接,一些额外的参数等)。
这就是我定义variant
和vector
类型的方式:
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。