【发布时间】:2023-03-16 16:42:01
【问题描述】:
有一个不受欢迎的 C 风格转换,我无法阻止它编译。不受欢迎的转换执行从某个类的对象到某个其他类的非常量引用的 C 样式转换。类是不相关的。同时,我喜欢支持从同一类的对象到 const 引用的 C 风格转换。我正在提供一个公共转换运算符来支持理想的演员表。在这种情况下,似乎不可能防止不受欢迎的演员表。
转换为非常量引用失败("Sandbox::B::operator Sandbox::A &()"(在第 30 行声明)不可访问*),不幸的是转换为 const 引用要么失败(错误:从“Sandbox::B”到“const Sandbox::A”的转换函数不止一个适用:
函数“沙盒::B::操作员常量沙盒::A &()”
函数“沙盒::B::操作员沙盒::A &()”):
#include <iostream>
#include <string>
#include <cstdlib>
namespace Sandbox {
class A {
public:
A (int i) : _x (i) { }
private:
int _x;
};
class B {
public:
B (const char* m) : _m (m), _a (std::atoi (m)) { }
/*
* This one shall be supported.
*/
operator const A& () {
return _a;
}
private:
/*
* This one shall be not supported.
* If this one is disabled both desired and undesired conversions pass the compilation.
*/
operator A& ();
const std::string _m;
const A _a;
};
}
int main () {
Sandbox::A a (1973);
Sandbox::B b ("1984");
/*
* This is the undesirable cast and it shall fail to compile.
*/
(Sandbox::A&)b;
/*
* This is the desirable cast and it shall pass the compilation.
*/
(const Sandbox::A&)b;
return 0;
}
如果我禁用运算符 operator A& () ,则会生成所需和不希望的转换。
我正在使用 gcc、icc 和 MSVC 编译。 我无法控制客户端代码并阻止使用 C 样式转换。
【问题讨论】:
-
会删除非常量版本并保持 const 版本达到您想要的效果吗?还是会将非常量版本默认为普通的 c 转换?
-
使用 cast 您可以从任何东西投射到任何东西,对此您无能为力。还是我错了?
-
为什么要支持 C-style cast?我的意思是,你为什么要编写 C 风格的演员表?当您使用
static_cast并且不定义非常量版本时,一切都按预期进行。 -
也许我遗漏了一些东西,但我不明白问题的重点。您有无法更改的蹩脚代码,并且您想阻止它编译。然后根本不编译它:)
-
如果他使用 C 风格的强制转换,你无法避免客户端代码抛弃 const-ness,因为 C 风格的强制转换允许抛弃 const-ness。 Simply don't use them; upgrade your client code to use
static_cast.
标签: c++ casting standards conversion-operator