У меня есть структура, состоящая из string
и time_point
, и я хочу, чтобы она демонстрировала поведение, подобное std::time_point
в C++20, с минимальным кодом, без явного определения всех операторов сравнения.
Как я могу этого добиться?
Мой код:
#include <iostream>
#include <chrono>
#include <string>
struct MyStruct {
std::string name;
std::chrono::system_clock::time_point time;
// Comparison operators
bool operator==(const MyStruct& other) const {
return time == other.time;
}
bool operator!=(const MyStruct& other) const {
return !(*this == other);
}
bool operator<(const MyStruct& other) const {
return time < other.time;
}
bool operator<=(const MyStruct& other) const {
return time <= other.time;
}
// Prefix increment operator
MyStruct& operator++() {
++time;
return *this;
}
// Postfix increment operator
MyStruct operator++(int) {
MyStruct temp = *this;
++(*this);
return temp;
}
// and so on...
};
@HowardHinnant, спасибо за ваш комментарий, я использую Linux и буду наследовать от time_point, как предложил Кристиан Штибер. Я не делал этого, потому что думал, что это неопределенное поведение.
Мой комментарий по-прежнему относится к дизайну наследования.
В C++20 вместо 6 операторов сравнения вам нужно определить только operator==
и operator<=>
(так называемый оператор космического корабля):
struct MyStruct {
std::string name;
std::chrono::system_clock::time_point time;
// Comparison operators
bool operator==(const MyStruct& other) const {
return time == other.time;
}
auto operator<=>(const MyStruct& other) const {
return time <=> other.time;
}
Все остальные операторы сравнения (<,>,<=,>=,!=) будут созданы из этих двух.
Однако для других операторов нет никакой магии, специфичной для C++20 (operator++
и т. д.).
Спасибо. Мне нужны и другие операторы. ++, -- и т. д.
Почему бы просто не сделать вашу структуру time_point?
struct MyStruct : public std::chrono::system_clock::time_point
{
std::string name;
};
Кроме того, на самом деле нет ничего постыдного в том, чтобы признать, что у вашего MyStruct
просто есть член time
, и просто выполнять операции непосредственно с ним. Что лучше соответствует реальному контексту: ваш MyStruct
на самом деле — это time_point
с именем или он просто сообщает нам о дне рождения какого-то парня?
Правильнее всего посмотреть на каждого члена в определенный момент времени и подумать, имеет ли это смысл для MyStruct. Судя по тому, как сформулирован вопрос, наверное, да.
@anatolyg, у меня возникла проблема. Если я вызову оператор++ и потеряю информацию о строке
@TedZach да, некоторые операторы создают новые объекты, и они создают только объекты своего класса, не принимая во внимание производные классы. Плохо, что я об этом забыл - мне редко нужна такая конструкция, а когда она мне нужна, меня обычно не волнует, что некоторые операторы не готовы на 100%...
К вашему сведению,
operator++()
собирается добавить кMyStruct
время, зависящее от платформы. В Linux это добавит 1нс. В Windows это добавит 100 нс. А в macOS это добавит 1000 нс (1 мкс). Это может быть то, что вы хотите. Но если это не так, вы можете это исправить, установивtime
определенную точность по вашему выбору. Например.std::chrono::sys_time<std::chrono::nanoseconds> time;
. Благодаря этому изменениюoperator++()
добавляет 1ns на всех платформах.