Eu tenho um pedaço de código SFINAE C++17
#include <type_traits>
template<typename>
constexpr bool dependentFalse = false;
template<typename T>
struct IAmEmpty
{
template<typename U=T, std::enable_if_t<dependentFalse<U>>* =nullptr>
auto deleteMe()
{}
};
template struct IAmEmpty<int>;
https://godbolt.org/z/vWW3favWj
Estou tentando retrabalhar isso para C++20 e me pergunto:
#include <type_traits>
template<typename T>
struct IAmEmpty
{
template<typename U=T>
requires false
void deleteMe() {}
void deleteMeToo() requires false {}
};
template struct IAmEmpty<int>;
Até onde eu entendo, o líder requer é próximo ao SFINAE pré-C++20 obtido usando eg enable_if
e void_t
similares. Portanto, deleteMe
é na verdade um modelo de função membro.
deleteMeToo
não é um modelo de função (ou estou errado aqui?). Exemplo ao vivo:
https://godbolt.org/z/rGzx8dz3f
Existem situações em que deleteMe
e deleteMeToo
realmente se comportam de forma diferente e deve-se ter cuidado ao preferir os requisitos finais em vez dos principais?
template <..> requires (..) void foo();
é equivalente atemplate <..> void foo() requires (..);
Portanto, é apenas estilo (ou possivelmente conveniência usar parâmetro de função emrequires
).A função sem modelo permite somente
requires
depois.Uma é uma função de modelo, enquanto a outra não é (elas ainda são entidades de modelo, da classe).
E as funções de modelo e não modelo têm algumas diferenças. O modelo tem/permite
Para migração, não há pontos para usar o modelo (que foi adicionado apenas para SFINAE), então
se tornaria
Você pode considerar transformar características
some_condition_v
em conceitos para permitir a subsunção .