Estou lendo a documentação em std::expected::operator==
, e aparentemente não é amigável ao SFINAE. Em vez de "não participa da resolução de sobrecarga se [os tipos não forem eq-comparáveis]", diz "o programa está malformado [nesse caso]".
E de fato:
#include <concepts>
#include <expected>
struct A {};
static_assert(!std::equality_comparable<std::expected<A, A>>);
Esta afirmação falha no MSVC e no Clang com libc++ e causa um erro grave no Clang com MSVC STL.
Mas por que não é compatível com SFINAE?
std::expected<T,U>
requer que ambos T
e U
sejam completos de qualquer forma, então aparentemente nada impede que todas as operações nele sejam compatíveis com SFINAE.
Acho que isso foi simplesmente ignorado.
Até abril de 2024, os
operator==
tipos de bibliotecas semelhantes, comostd::pair
,std::tuple
,std::optional
,std::variant
etc., também não eram compatíveis com SFINAE nesse sentido.Eles foram tornados compatíveis com SFINAE com P2944R3, o que também indica que isso provavelmente aconteceu sem nenhuma intenção por trás disso.
As mudanças de redação estão listadas no artigo a partir daqui . Se uma cláusula originalmente dizia " Mandates: ", isso significa que se a condição não foi satisfeita, o programa estava malformado (ou seja, um erro grave). Se originalmente dizia " Preconditions: ", então não satisfazer a condição fez com que o programa tivesse um comportamento indefinido. Quando agora diz " Constraints: ", então não satisfazer a condição significa que a sobrecarga não participa da resolução de sobrecarga (ou seja, é amigável ao SFINAE).
Meu palpite é que isso
std::expected
também foi esquecido.