c++ - boost optional and user-defined conversion -
i unable write correct user defined conversion type item
. i've tried:
#include <iostream> #include <boost/optional.hpp> struct { int x; }; struct item { boost::optional<int> x_; item(){} item(const a& s) : x_(s.x) { } operator boost::optional<a>() const { boost::optional<a> s; if (x_) { s->x = *x_; } return s; } }; std::vector<a> geta(const std::vector<item> &items) { std::vector<a> a; (const auto &i : items) { if (i.x_) { a.push_back(*static_cast<boost::optional<a>>(i)); // <- line causes error } } return a; }
that how use it:
int main() { a; a.x = 3; item i(a); auto v = geta({i}); return 0; }
g++ -std=c++11
says:
in file included /usr/include/boost/optional.hpp:15:0, test.cpp:2: /usr/include/boost/optional/optional.hpp: in instantiation of ‘void boost::optional_detail::optional_base<t>::construct(const expr&, const void*) [with expr = item; t = a]’: /usr/include/boost/optional/optional.hpp:262:25: required ‘boost::optional_detail::optional_base<t>::optional_base(const expr&, const expr*) [with expr = item; t = a]’ /usr/include/boost/optional/optional.hpp:559:78: required ‘boost::optional<t>::optional(const expr&) [with expr = item; t = a]’ test.cpp:30:55: required here /usr/include/boost/optional/optional.hpp:392:8: error: no matching function call ‘a::a(const item&)’ new (m_storage.address()) internal_type(expr) ; ^ /usr/include/boost/optional/optional.hpp:392:8: note: candidates are: test.cpp:3:8: note: a::a() struct ^ test.cpp:3:8: note: candidate expects 0 arguments, 1 provided test.cpp:3:8: note: constexpr a::a(const a&) test.cpp:3:8: note: no known conversion argument 1 ‘const item’ ‘const a&’ test.cpp:3:8: note: constexpr a::a(a&&) test.cpp:3:8: note: no known conversion argument 1 ‘const item’ ‘a&&’
why try find a
struct constructor instead of use user defined conversion operator?
you may point me directly position of user-defined conversion page because unable find reason this. example,
user-defined conversion function invoked on second stage of implicit conversion, consists of 0 or 1 converting constructor or 0 or 1 user-defined conversion function.
in opinion directly says if no conversion constructor defined user-defined conversion function used. wrong? , if yes, how can implement user-defined conversion without defining conversion cunstructor in struct a
?
you have 2 issues code. optional
operator never initializes boost::optional
. if don't that, accessing members undefined behavior. have is:
operator boost::optional<a>() const { boost::optional<a> s; if (x_) { s = a{*x_}; } return s; }
the second issue when do:
static_cast<boost::optional<a>>(i);
that equivalent to:
boost::optional<a> __tmp(i);
but turns out boost::optional
has explicit
template constructor. preferred conversion function. error you're seeing compiling going down path of factory constructor, item
not such factory.
you use boost::optional<a>
directly:
std::vector<a> geta(const std::vector<item> &items) { std::vector<a> a; (boost::optional<a> opt : items) { if (opt) { a.push_back(*opt); } } return a; }
or, since constructor template explicit
, use conversion operator in non-explicit context:
boost::optional<a> opt = i; a.push_back(*opt);
this has added benefit of being easier read.
Comments
Post a Comment