【发布时间】:2022-01-09 03:27:31
【问题描述】:
假设我有一个简单的Duration 类:
class Duration
{
int seconds;
public:
Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30);
t = 60;
}
我决定我不喜欢从int 隐式转换为Duration。我可以让构造函数explicit:
class Duration
{
int seconds;
public:
explicit Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30); // This is fine, conversion is explicit
t = 60; // Doesn't compile: implicit conversion no longer present for operator=
}
但是如果我不想立即中断所有隐式转换为Duration 的调用代码怎么办?我想要的是这样的:
class Duration
{
int seconds;
public:
[[deprecated]]
Duration(int t_seconds) : seconds(t_seconds) { }
explicit Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30); // Compiles, no warnings, uses explicit constructor
t = 60; // Compiles but emits a deprecation warning because it uses implicit conversion
}
这将允许在识别当前依赖隐式转换的任何地方的同时编译现有代码,因此可以将它们重写为使用显式转换(如果它打算)或重写以具有正确的行为(如果不是)。
但是这是不可能的,因为我不能用Duration::Duration(int) 重载Duration::Duration(int)。
除了“使转换显式,接受调用代码在您编写适当的更改之前不会编译”之外,有没有办法实现类似的效果?
【问题讨论】:
-
是否可以为隐式转换打开编译器警告?以 gcc 中的
-Wconversion为例。 -
在这种情况下,emit a warning 实际上并没有出现。不过,按照这些思路可能就足够了。
-
你可以通过条件编译来做到这一点,#ifdef REFACTOR explicit Duration(int) #else Duration(int)。然后逐个项目编译并定义 REFACTOR(命令行)测试代码。完成所有项目后,删除 ifdef 和所有定义(或相反从所有项目上的定义开始并一个一个删除)
标签: c++ type-conversion