c++ - 为什么这不对转换构造函数进行隐式转换?
问题描述
所以我有这个代码:
struct Foo {
Foo() { cout << "default\n"; }
Foo(const long long) { cout << "implicit\n"; }
};
struct Bar {
Bar(const short param) : param(param) {}
operator long long() const { return static_cast<long long>(param); }
const short param;
};
我原以为Foo foo = Bar(13)
会使用我的隐式强制转换,然后使用转换构造函数。但它错误:
错误:请求从
Bar
非标量类型转换Foo
不过,这很好用:Foo foo(Bar(13))
. 为什么我的隐式转换用于显式转换构造,而不用于隐式转换构造?
我从https://en.cppreference.com/w/cpp/language/copy_initialization得到的规则说:
转换的结果,如果使用了转换构造函数,则为纯右值表达式,然后用于直接初始化对象
解决方案
首先从 to 的隐式转换和从to的Bar
隐式转换都是用户定义的转换。long long
long long
Foo
Foo foo = Bar(13);
执行复制初始化,编译器会尝试隐式Bar
转换。Foo
需要进行两次隐式转换,即先转换Bar
为long long
,然后再转换long long
为Foo
. 但在一个隐式转换序列中只允许进行一次用户定义的转换。
隐式转换序列包含以下内容,按此顺序:
1) 零个或一个标准转换序列;
2) 零次或一次用户自定义转换;
3) 零或一标准转换序列。
用户定义的转换由零个或一个非显式单参数构造函数或非显式转换函数调用组成
Foo foo(Bar(13));
执行直接初始化。将检查的构造函数,Foo
并通过重载决议选择最佳匹配。只需要一个隐式的用户定义转换(从Bar
到long long
);之后直接Foo::Foo(long long)
调用构造foo
。
推荐阅读
- javascript - 基于相同的 JSON 键值获取值
- c# - 如何在没有实体框架的 asp.net Mvc 中使用 CheckBox 删除多条记录
- c - 我可以将 UTF8 存储在 C 样式的字符数组中吗
- google-cloud-platform - 使用 gsutil 从本地服务器通过边界防火墙连接到 Google Cloud Storage
- excel - 基于包含某些字符串的列标题值删除excel宏中整列的方法
- python - Gst-python 已安装,但找不到插件
- c# - SetServiceStatus 内的参数
- performance - elasticsearch - 提高查询性能
- python - Pandas:取消组合并融化空格缩进的记录
- python - 使用 PyMongo 用自己的值更新所有 MongoDB 字段