[英]Trying to use spaceship operator in derived classes
I am trying to use spaceship operator in base class so I would have defined all operator by compilator.我正在尝试在基础 class 中使用宇宙飞船运算符,因此我将通过编译器定义所有运算符。 (source: https://devblogs.microsoft.com/cppblog/simplify-your-code-with-rocket-science-c20s-spaceship-operator/ )
(来源: https://devblogs.microsoft.com/cppblog/simplify-your-code-with-rocket-science-c20s-spaceship-operator/ )
But I encountered problem which I do not understand.但是我遇到了我不明白的问题。
Source Code: https://godbolt.org/z/SZnNfK源代码: https://godbolt.org/z/SZnNfK
#include <chrono>
#include <cassert>
#include <iostream>
#define USE_SPACESHIP
class ITimestampWrapper
{
public:
ITimestampWrapper() noexcept
: _timestamp(std::chrono::steady_clock::now())
{
}
explicit ITimestampWrapper(std::chrono::steady_clock::time_point timestamp) noexcept
: _timestamp(timestamp)
{
}
#ifndef USE_SPACESHIP
friend bool operator<(const ITimestampWrapper& lhs, const ITimestampWrapper& rhs)
{
return lhs._timestamp < rhs._timestamp;
}
friend bool operator>(const ITimestampWrapper& lhs, const ITimestampWrapper& rhs)
{
return lhs._timestamp > rhs._timestamp;
}
#else
friend auto operator<=>(const ITimestampWrapper&, const ITimestampWrapper&) = default;
#endif
virtual ~ITimestampWrapper() = default;
private:
std::chrono::steady_clock::time_point _timestamp;
};
class testClass : public ITimestampWrapper
{
public:
testClass() = default;
explicit testClass(std::chrono::steady_clock::time_point test)
: ITimestampWrapper(test)
{
}
int _x = 0;
};
class testClass2 : public ITimestampWrapper
{
public:
testClass2() = default;
explicit testClass2(std::chrono::steady_clock::time_point test)
: ITimestampWrapper(test)
{
}
int _x = 0;
};
int main()
{
auto testTime = std::chrono::steady_clock::now();
testClass A;
A._x = 50000;
testClass B(testTime);
B._x = 6000;
if(A > B)
{
std::cout << "Correct A is older than B" << std::endl;
}
else
{
std::cout << "Wrong A is older than B" << std::endl;
}
auto testTime2 = std::chrono::steady_clock::now();
testClass AA;
AA._x = 50000;
testClass2 BB(testTime2);
BB._x = 6000;
if(AA > BB)
{
std::cout << "Correct AA is older than BB" << std::endl;
}
else
{
std::cout << "Wrong AA is older than BB" << std::endl;
}
}
Output: Output:
WITH USE_SPACESHIP:
使用 USE_SPACESHIP:
Correct A is older than B
正确的 A 比 B 更老
Wrong AA is not older than BB // <--- This is wrong, AA is older
错误的 AA 不比 BB 旧 // <--- 这是错误的,AA 是旧的
WITHOUT USE_SPACESHIP:
没有使用太空船:
Correct A is older than B
正确的 A 比 B 更老
Correct AA is older than BB
正确的 AA 早于 BB
When I implement operators < and > in base class by myself, comparsion is working even If I am comparing different classes with same base.当我自己在基础 class 中实现运算符 < 和 > 时,即使我正在比较具有相同基础的不同类,比较仍然有效。
But when I use the spaceship operator, the comparsion is working only when applied to the same ClassType with same base.但是当我使用 spaceship 运算符时,比较仅在应用于具有相同基数的相同 ClassType 时才有效。
How do these two approaches differs?这两种方法有何不同?
Note: I do want to compare only the timestamps of the base class not any other mambers of base class nor derived class注意:我只想比较基本 class 的时间戳,而不是基本 class 的任何其他成员,也不是派生的 class
Undefine the USE_SPACESHIP macro for using classical operator overload取消定义使用经典运算符重载的 USE_SPACESHIP 宏
Thank you.谢谢你。
Edit: I tried to use CRTP approach but came to same problem.编辑:我尝试使用 CRTP 方法,但遇到了同样的问题。
I suppose this is a bug of GCC.我想这是 GCC 的错误。 As you can see in this assembly here :
正如您在此程序集中看到的:
mov eax, OFFSET FLAT:vtable for testClass+16
cmp rax, OFFSET FLAT:vtable for testClass2+16
Gcc compares member of the vtable: it compares the static type of AA and the static type of BB, not the timestamp. Gcc 比较 vtable 的成员:它比较 AA 的 static 类型和 BB 的 static 类型,而不是时间戳。
It works if you omit the -O3
or if you provide -O0
.如果您省略
-O3
或提供-O0
,它会起作用。 It also fails for -O1
and -O2
.它也失败了
-O1
和-O2
。 Looks like a compiler bug (or undefined behaviour somewhere).看起来像编译器错误(或某处未定义的行为)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.