Jak porównać podpis dwóch funkcji?

35

Czy istnieje sposób sprawdzenia, czy dwie funkcje mają taki sam podpis? Na przykład:

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

W tym przykładzie, funAi funBjest jedynym połączeniem funkcji, które powinny powrócić true.

Stefano Pittalis
źródło

Odpowiedzi:

39

Zasadniczo chcesz sprawdzić, czy typy dwóch funkcji są takie same:

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

Nie nazwałbym tego „porównywaniem podpisów”, ponieważ, jeśli dobrze pamiętam, typ zwracany nie jest częścią podpisu (ponieważ nie wpływa to na rozdzielczość przeciążenia).

HolyBlackCat
źródło
20
Typ zwracany uczestniczy w rozwiązywaniu przeciążeń wskaźników funkcji i jest częścią podpisu dla szablonów funkcji .
Davis Herring
15

Możesz sprawdzić typ funkcji za pomocą decltypei std::is_same. na przykład

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

RELACJA NA ŻYWO

songyuanyao
źródło
14

Inni wspominali o rozwiązaniu, używając std::is_samei decltype.

Teraz, aby uogólnić porównanie dowolnej liczby podpisów funkcji, możesz wykonać następujące czynności

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

i porównaj tyle funkcji, ile jedna

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

( Zobacz demo na żywo )


Lub dla mniej pisania (tj. Bez decltype), uczyń to jako funkcję

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

i zadzwoń po prostu

areSameFunctions(funA, funB, funC) 

( Zobacz demo na żywo )

JeJo
źródło
3

Jako inną możliwość, która nie została wymieniona: można korzystać typeidz typeinfoi ==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;
SS Anne
źródło
GCC daje mi error: non-constant condition for static assertion.
HolyBlackCat,
1
@HolyBlackCat Ah, to jest RTTI. Nie wiedziałem, że tak nie było constexpr. Mam teraz nieco lepszy przykład.
SS Anne,