¿Cómo comparar la firma de dos funciones?

35

¿Hay alguna manera de verificar si dos funciones tienen la misma firma? Por ejemplo:

int funA (int a, int b);
int funB (int a, int b);
float funC (int a, int b);
int funD (float a, int b);

En este ejemplo, funAy funBes la única combinación de funciones que debería regresar true.

Stefano Pittalis
fuente

Respuestas:

39

Esencialmente, desea verificar si los tipos de dos funciones son iguales:

std::is_same_v<decltype(funA), decltype(funB)>

No llamaría a esto 'comparar firmas', ya que, si no recuerdo mal, el tipo de retorno no es parte de una firma (porque no afecta la resolución de sobrecarga).

HolyBlackCat
fuente
20
Un tipo de retorno participa en la resolución de sobrecarga para los punteros de función , y es parte de la firma de las plantillas de función .
Davis Herring
14

Otros han mencionado la solución usando std::is_samey decltype.

Ahora, para generalizar la comparación de un número arbitrario de firmas de funciones, puede hacer lo siguiente

#include <type_traits> // std::is_same, std::conjunction_v

template<typename Func, typename... Funcs>
constexpr bool areSameFunctions = std::conjunction_v<std::is_same<Func, Funcs>...>;

y compara tantas funciones como quieras

areSameFunctions<decltype(funA), decltype(funB), decltype(funC)>

( Ver demostración en vivo )


O para escribir menos (es decir, sin decltype), hágalo como una función

template<typename Func, typename... Funcs>
constexpr bool areSameFunctions(Func&&, Funcs&&...)
{
   return std::conjunction_v<std::is_same<Func, Funcs>...>;
}

y llama simplemente por

areSameFunctions(funA, funB, funC) 

( Ver demostración en vivo )

JeJo
fuente
3

Como otra posibilidad que no se ha mencionado: puede usar typeiddesde typeinfoy ==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;
SS Anne
fuente
GCC me da error: non-constant condition for static assertion.
HolyBlackCat
1
@HolyBlackCat Ah, esto es RTTI. No sabía que no lo eran constexpr. Tengo un ejemplo un poco mejor ahora.
SS Anne