在 C++ 中链接用户转化
Chaining user conversions in c++
考虑以下代码段:
#include <iostream>
struct C
{
C()
{
std::cout << "C()n";
}
explicit C(const C&)
{
std::cout << "C(const C&)n";
}
operator int()
{
std::cout << "int()n";
return 1;
}
C(int)
{
std::cout << "C(int)n";
}
};
int main()
{
C c1;
std::cout << 'n';
C c2 = c1;
std::cout << 'n';
C c3(c1);
}
g++
和clang
都给出以下输出:
C()
int()
C(int)
C(const C&)
这是否违反了隐式转换序列最多可以包含一个用户转换的规则?
这只会编译,因为您正在初始化类C
,并在第C c2 = c1;
行中使用它自己。如果你有一个类D
它的行为与C
相同并尝试D d; C c = d;
,它不会编译,原因如下:因为隐式转换需要两个用户定义的转换。恶魔
当使用同一个类时,它编译的原因是当y
类型为A
或派生自它时,复制初始化(A x = y;
)的行为不同。在这种情况下,选择一个转换构造函数,然后使用参数y
调用该构造函数,这可能会导致隐式转换。构造函数调用本身不是隐式转换的一部分。
因此,在您的代码中,转换序列仅包含一个用户定义的转换:C
到int
,因为构造函数C(int)
是单独调用的。
见C++14 8.5/17:
- 如果初始化是直接初始化,或者如果是复制初始化,其中 cv 不合格 源类型的版本与目标的类是同一类或派生类, 考虑构造函数。枚举适用的构造函数 (13.3.1.3),并且最好的 通过过载分辨率 (13.3) 选择一个。调用如此选择的构造函数来初始化 对象,初始值设定项表达式或表达式列表作为其参数。
- 否则(即,对于剩余的复制初始化情况),用户定义的转换序列 可以从源类型转换为目标类型或(当转换函数时) 被使用)到其派生类被枚举 [...]
在 http://en.cppreference.com/w/cpp/language/copy_initialization 阅读更多内容。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 从链接列表c++中删除一个项目
- g++用户定义的动态链接库上的全局new和delete运算符
- VS2015 未链接用户32.lib
- 链接列表(C )中(字符串)数据的用户输入
- C 链接的列表用户输入限制验证导致程序结束
- 根据用户配置在运行时链接共享对象
- 提示用户填写链接列表
- 生产者-消费者队列 - std::queue 或用户编写的链接列表
- CMake用户构建的库;无法为目标指定链接库
- 如何在用户单击wxWidget事件时打开Web链接
- 如何在Qt的默认用户浏览器中打开链接
- 正在检查链接列表(C++)中的用户输入
- 为任何用户动态获取PC上桌面的链接
- 库设计:允许用户在"header-only"和动态链接之间做出决定?
- CMake:在静态库上设置一个链接器标志,供用户在链接时使用(Visual Studio)
- 与用户定义的共享库链接错误
- 您是否可以拥有一个具有管理员权限的DLL,该DLL从仅具有用户级权限的客户端应用程序链接
- 用户定义的dll引用另一个用户定义的dll时发生链接器错误