我正在编写一个具有各种运算符重载的类,它应该是某些"外部"代码中float
(或类似)的直接替代品。 特别是,我想支持 3 个示例用法(见下文),我找不到一种方法来满足所有 3 个用法来定义我的类。
可能吗?
旁白:事实上,我正在尝试在Lua 5.3中实现自定义lua_Number
类型,该类型通常是float
或double
。我正在将Lua编译为C++,并尝试使用定点表示。虽然我确实可以更改"外部"代码(因为它只是嵌入式Lua),但我宁愿不(:
实时代码链接,如果你想玩:https://godbolt.org/z/37c6nj
以下是我需要支持的 3 个用例:
示例 1:MyNum 是工会成员的简单用法。 这意味着我不能有奇特的复制构造函数之类的,因为这些的"非平凡"版本会导致联合格式不正确(未经修改)。
SomeUnion x;
x.num = 123.0f;
SomeUnion y = x;
示例 2:MyNum 是联合的成员(如上所述),该联合是结构的成员。我不确定这与第一个示例有何不同,b ut 它是我当前代码版本中的最后一个症结所在。这是当前未在链接示例中编译的位。
SomeStruct s1;
s1.u.num = x.num;
SomeStruct s2;
// With all the code as-is, this is the line that fails:
// error: use of deleted function 'SomeStruct& SomeStruct::operator=(const SomeStruct&)'
// note: 'SomeStruct& SomeStruct::operator=(const SomeStruct&)' is implicitly deleted because the default definition would be ill-formed
s2 = s1;
示例 3:有关volatile
的用法。这需要自定义operator=
。
volatile SomeUnion v;
// If we don't have a custom operator= with 'volatile' qualifier, we get:
// ERROR: passing 'volatile MyNum' as 'this' argument discards qualifiers [-fpermissive]
v.num = x.num;
如果我删除operator=
的volatile
实现,则示例 1 和示例 2 编译,但示例 3 不会。
如果我包含operator=
的volatile
版本,则示例 1 和示例 3 编译,但示例 2 不会。
有没有办法让它们都工作?
或者,如果做不到这一点,对外部代码进行"微创"更改以允许其工作的任何想法?
也许最简单的方法是将互操作性所需的联合定义为:
union SomeUnion {
uint32_t num;
void * pFoo;
void set(const MyNum& myNum) {
num = *reinterpret_cast<const uint32_t*>(&myNum);
}
MyNum get() {
return *reinterpret_cast<MyNum*>(&this->num);
}
};
MyNum 副本应该只是默认的:
MyNum(const MyNum& other) = default;
MyNum& operator=(const MyNum& other) = default;
这种联合非常适合任何低级操作,如volatile
,因为它只涉及基元类型;另一方面,使用 getter 和 setter 方法将num
字段用作MyNum
对象的存储很容易。