Boost可选和用户定义的转换
boost optional and user-defined conversion
我无法为类型Item
编写正确的用户定义转换。这是我尝试过的:
#include <iostream>
#include <boost/optional.hpp>
struct A
{
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;
for (const auto &i : items) {
if (i.x_) {
a.push_back(*static_cast<boost::optional<A>>(i)); // <- this line causes error
}
}
return a;
}
我就是这么用的:
int main() {
A a;
a.x = 3;
Item i(a);
auto v = getA({i});
return 0;
}
g++ -std=c++11
说:
In file included from /usr/include/boost/optional.hpp:15:0,
from 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 from ‘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 from ‘boost::optional<T>::optional(const Expr&) [with Expr = Item; T = A]’
test.cpp:30:55: required from here
/usr/include/boost/optional/optional.hpp:392:8: error: no matching function for call to ‘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 A
^
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 for argument 1 from ‘const Item’ to ‘const A&’
test.cpp:3:8: note: constexpr A::A(A&&)
test.cpp:3:8: note: no known conversion for argument 1 from ‘const Item’ to ‘A&&’
为什么它试图找到A
结构构造函数,而不是使用用户定义的转换操作符?
你可以直接指向用户定义转换页面的任何位置,因为我找不到任何原因。例如,
在我看来,用户定义转换函数在隐式转换的第二阶段调用,第二阶段由0个或1个转换构造函数或 0个或1个用户定义转换函数组成。
直接表示,如果没有定义转换构造函数,则使用用户定义的转换函数。我错了吗?如果是,我如何实现用户定义的转换,然后不定义转换构造函数在struct A
?
您的代码有两个问题。optional
操作符从不初始化boost::optional
。如果不这样做,访问成员就是未定义行为。你要做的是:
operator boost::optional<A>() const {
boost::optional<A> s;
if (x_) {
s = A{*x_};
}
return s;
}
第二个问题是当你这样做的时候:
static_cast<boost::optional<A>>(i);
相当于:
boost::optional<A> __tmp(i);
但是boost::optional
有一个explicit
模板构造函数。这比你的转换函数要好。您看到的错误是沿着这个工厂构造函数的路径编译,其中Item
不是这样一个工厂。
您可以直接使用boost::optional<A>
:
std::vector<A> getA(const std::vector<Item> &items) {
std::vector<A> a;
for (boost::optional<A> opt : items) {
if (opt) {
a.push_back(*opt);
}
}
return a;
}
或者,由于构造函数模板是explicit
,您可以在非显式上下文中使用转换操作符:
boost::optional<A> opt = i;
a.push_back(*opt);
相关文章:
- 仅为某些模板专用化定义转换运算符:预期类型/预期类型说明符
- 模拟返回具有多个用户定义转换的类型的方法
- 是否可以使用明确的模板参数调用模板的用户定义转换操作员
- 使用自定义转换运算符的不明确性
- C++显式积分用户定义转换
- 解决隐藏歧义的不明确用户定义转换
- 如何自定义转换模板参数
- 用户定义转换的第二个标准转换序列
- 如何将串联的定义转换为RC文件中的字符串
- 是否可以用C++编写自定义转换运算符(如“static_cast”)
- Qt4:QGraphicsScene/View和自定义转换方法
- 如何将c结构体定义转换为c++
- 如何在VS2008中将#define定义转换为字符串
- 为什么模板化的用户定义转换操作符能够确定其返回类型?
- #定义转换为LPCSTR或std::string的字符串
- 错误无效的用户定义转换
- 无效的用户定义转换错误
- 是否有方法为任何指针类型定义转换操作符
- Visual C++ 不存在从"myClass1"到"myClass1"的合适用户定义转换
- 提振.Python自定义转换器