Médio C++

Comparação com operador <=> (C++20)

Enunciado

Implemente uma classe Data com dia, mês e ano (inteiros). Use o operador <=> (three-way comparison) para gerar automaticamente todos os operadores relacionais (==, !=, <, <=, >, >=). No main, compare duas datas e imprima o resultado de d1 < d2, d1 == d2 e d1 >= d2.

Requisitos

  • A classe Data deve ter os membros dia, mes, ano como int.
  • O operator<=> deve ser declarado como auto operator<=>(const Data&) const = default;.
  • O programa deve imprimir os resultados das três comparações.
  • A saída deve ser 1 para verdadeiro e 0 para falso.

Código inicial

#include <iostream>
#include <compare>

class Data {
public:
    int dia, mes, ano;
    Data(int d, int m, int a) : dia(d), mes(m), ano(a) {}
    // TODO: declarar operator<=> como default
};

int main() {
    Data d1(15, 3, 2024);
    Data d2(20, 3, 2024);
    std::cout << (d1 < d2) << '\n';
    std::cout << (d1 == d2) << '\n';
    std::cout << (d1 >= d2) << '\n';
    return 0;
}

Saída esperada

1
0
0
Ver dica

Inclua <compare> e use auto operator<=>(const Data&) const = default; dentro da classe. O compilador gera os demais operadores automaticamente.

Mostrar solução
#include <iostream>
#include <compare>

class Data {
public:
    int dia, mes, ano;
    Data(int d, int m, int a) : dia(d), mes(m), ano(a) {}

    // Operador three-way default: gera ==, !=, <, <=, >, >=
    auto operator<=>(const Data&) const = default;
};

int main() {
    Data d1(15, 3, 2024);
    Data d2(20, 3, 2024);
    std::cout << (d1 < d2) << '\n';
    std::cout << (d1 == d2) << '\n';
    std::cout << (d1 >= d2) << '\n';
    return 0;
}

Passo a passo

  1. Incluímos <compare> para ter acesso ao operador <=>.
  2. Definimos a classe Data com três inteiros e um construtor.
  3. Declaramos auto operator<=>(const Data&) const = default;. O default faz o compilador comparar membro a membro na ordem de declaração (dia, depois mês, depois ano).
  4. Como <=> é padrão, o compilador gera automaticamente todos os operadores relacionais: ==, !=, <, <=, >, >=.
  5. No main, usamos esses operadores diretamente, sem implementá-los manualmente.

Por que funciona

O operador <=> (three-way comparison) retorna um tipo que indica se um valor é menor, igual ou maior que outro. Quando definido como default, o compilador sintetiza a comparação lexicográfica dos membros. A partir dele, os operadores ==, <, etc. são reescritos pelo compilador. Isso elimina a necessidade de escrever seis operadores manualmente.

Erros comuns

  • Esquecer de incluir <compare>: o código não compila.
  • Declarar operator<=> sem = default e sem implementação: erro de linker.
  • Ordem dos membros: a comparação padrão usa a ordem de declaração; se ano fosse declarado antes de dia, a comparação seria lexicográfica por ano, depois dia, o que pode não ser o desejado.

Outra forma de resolver

Implementar manualmente operator< e operator==, e derivar os demais:

bool operator<(const Data& a, const Data& b) { /* ... */ }
bool operator==(const Data& a, const Data& b) { /* ... */ }

Mas isso é mais verboso e propenso a erros. A abordagem com <=> é preferível em C++20.

Saída esperada

1
0
0