我想查看使用C ++ 3.0驱动程序从MongoDB检索单个文档的结果。 driver documentation描述了view() method类的bsoncxx::document::value(由mongocxx::collection::find_one返回)。当我试图像这样使用它时:
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/document/value.hpp>
#include <mongocxx/instance>
#include <mongocxx/client>
mongocxx::instance inst{};
mongocxx::client conn{};
bsoncxx::document::view doc;
auto db = conn["test"];
try {
auto docObj = db["collection"].find_one(document{} <<
"field" << "value" << finalize);
doc = docObj.view();
} catch (mongocxx::exception::query e) {
std::cerr << "Couldn't retrieve document";
return NULL;
}
...
我收到以下编译错误:
error: 'struct core::v1::optional<bsoncxx::v0::document::value>' has no member named 'view'
在
行doc = docObj.view();
我做错了什么?如果这不是使用find_one()
的正确习惯用语,那么我应该使用什么呢?
答案 0 :(得分:3)
找到它。 bsoncxx :: optional模板意味着bsoncxx :: document :: value的成员可用作var-&gt;成员。上面的代码应该是:
doc = docObj->view();
令人困惑,因为docObj是一个对象,而不是一个指针,而是一个呈现其底层对象的对象,就像它是一个指针一样。
答案 1 :(得分:-1)
core::v1::optional<T>
的行为与std::experimental::optional<T>
非常相似。
正如pandas.DataFrame.info()
的文档中所述(或者,自c ++ 17,std::experimental::optional),
当optional类型的对象为std::optional时,如果对象包含值,则转换返回true;如果不包含值,则返回false。
你必须通过对其应用运算符bool来检查你的docObj是否包含值,因为
如果* this不包含值
,则[operator *]的行为未定义
(描述了一些bad_optional_access异常,但是operator*
的文档说当没有值时尝试访问包含的值会导致UB)
因此,您的代码必须看起来像
if(docObj) {
doc docObj->view();
} else {
//Throw an exception? log an error to console?
//Do nothing?
std::cerr << "find_one() failed for" << std::endl <<
bsoncxx::to_json(
document{} << "field" << "value" << finalize
) << std::endl;
}
如果由于某种原因find_one()
失败,这可能会有所帮助。
是的,core::v1::optional<T>
和std::optional
的实施可能会有所不同(至少我无法在contextually converted to bool找到它)。
但是最好检查一下。
UPD:如official api documentation所示,我(部分?)正确:它可以使用std :: experimental :: optional