Como comparar a assinatura de duas funções?

35

Existe uma maneira de verificar se duas funções têm a mesma assinatura? Por exemplo:

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

Neste exemplo, funAe funBé a única combinação de funções que deve retornar true.

Stefano Pittalis
fonte

Respostas:

39

Essencialmente, você deseja verificar se os tipos de duas funções são iguais:

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

Eu não chamaria isso de 'comparação de assinaturas', pois, se bem me lembro, o tipo de retorno não faz parte de uma assinatura (porque não afeta a resolução de sobrecarga).

HolyBlackCat
fonte
20
Um tipo de retorno participa da resolução de sobrecarga para ponteiros de função e faz parte da assinatura para modelos de função .
Davis Herring
15

Você pode verificar o tipo de função com decltypee std::is_same. por exemplo

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

VIVER

songyuanyao
fonte
14

Outros mencionaram a solução usando std::is_samee decltype.

Agora, para generalizar a comparação para um número arbitrário de assinaturas de funções, você pode fazer o seguinte

#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>...>;

e compare tantas funções quanto uma

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

( Veja demonstração ao vivo )


Ou, para menos digitação (ou seja, sem decltype), faça isso como uma função

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

e ligue simplesmente

areSameFunctions(funA, funB, funC) 

( Veja demonstração ao vivo )

JeJo
fonte
3

Como outra possibilidade que não foi mencionada: você pode usar typeidde typeinfoe ==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;
SS Anne
fonte
O GCC me dá error: non-constant condition for static assertion.
HolyBlackCat
11
@HolyBlackCat Ah, isso é RTTI. Não sabia que estes não eram constexpr. Eu tenho um exemplo um pouco melhor agora.
SS Anne