fundo
Sabemos que o conceito std::same_as
é agnóstico em ordem (em outras palavras, simétrico): std::same_as<T, U>
é equivalente a std::same_as<U, T>
( questão relacionada ). Nesta pergunta, eu gostaria de implementar algo mais geral: template <typename ... Types> concept same_are = ...
que verifique se os tipos no pacote Types
são iguais entre si.
Minha tentativa
#include <type_traits>
#include <iostream>
#include <concepts>
template <typename T, typename... Others>
concept same_with_others = (... && std::same_as<T, Others>);
template <typename... Types>
concept are_same = (... && same_with_others<Types, Types...>);
template< class T, class U> requires are_same<T, U>
void foo(T a, U b) {
std::cout << "Not integral" << std::endl;
}
// Note the order <U, T> is intentional
template< class T, class U> requires (are_same<U, T> && std::integral<T>)
void foo(T a, U b) {
std::cout << "Integral" << std::endl;
}
int main() {
foo(1, 2);
return 0;
}
(Minha intenção aqui é enumerar todos os tipos possíveis de tipos ordenados no pacote)
Infelizmente, esse código não seria compilado , com o compilador reclamando que a chamada para foo(int, int)
é ambígua. Acredito que considere are_same<U, T>
e are_same<T, U>
como não equivalente. Gostaria de saber por que o código falha, como posso corrigi-lo (para que o compilador os trate como equivalentes)?
... Types
são iguais? Talvez std :: joint possa ajudá-lo. Há um exemplo na parte inferior da página que parece semelhante à sua abordagem.
same_with_others
em todas as permutações possíveis dos tipos.