Antecedentes
Sabemos que el concepto std::same_as
es agnóstico al orden (en otras palabras, simétrico): std::same_as<T, U>
es equivalente a std::same_as<U, T>
( pregunta relacionada ). En esta pregunta, me gustaría implementar algo más general: template <typename ... Types> concept same_are = ...
que verifique si los tipos en el paquete Types
son iguales entre sí.
Mi intento
#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;
}
(Mi intención aquí es enumerar todos los pares de tipos ordenados posibles en el paquete)
Desafortunadamente, este código no se compilaría , ya que el compilador se queja de que la llamada a foo(int, int)
es ambigua. Creo que lo considera are_same<U, T>
y are_same<T, U>
como no equivalente. Me gustaría saber por qué el código falla y cómo puedo solucionarlo (para que el compilador los trate como equivalentes).
... Types
son iguales? Tal vez std :: conjunción pueda ayudarte. Hay un ejemplo en la parte inferior de la página que parece similar a su enfoque.
same_with_others
en cada permutación posible de los tipos.