Как сравнить сигнатуру двух функций?

35

Есть ли способ проверить, имеют ли две функции одинаковую подпись? Например:

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

В этом примере funAи funBесть единственная комбинация функций, которую следует вернуть true.

Стефано Питталис
источник

Ответы:

39

По сути, вы хотите проверить, совпадают ли типы двух функций:

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

Я бы не назвал это «сравнением сигнатур», поскольку, если я правильно помню, тип возвращаемого значения не является частью сигнатуры (поскольку он не влияет на разрешение перегрузки).

HolyBlackCat
источник
20
Тип возвращаемого значения участвует в разрешении перегрузки для указателей на функции и является частью сигнатуры для шаблонов функций .
Дэвис Херринг
14

Другие упоминали решение с использованием std::is_sameи decltype.

Теперь, чтобы обобщить сравнение для произвольного числа сигнатур функций, вы можете сделать следующее

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

и сравнить столько функций, сколько нравится

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

( Смотрите Live Demo )


Или для меньшего набора текста (т.е. без decltype), сделайте это как функцию

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

и позвонить просто

areSameFunctions(funA, funB, funC) 

( Смотрите Live Demo )

JeJo
источник
3

В качестве еще одной возможности, которая не была упомянута: вы можете использовать typeidиз typeinfoи ==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;
СС Энн
источник
GCC дает мне error: non-constant condition for static assertion.
HolyBlackCat
1
@HolyBlackCat Ах, это RTTI. Не знал, что это не так constexpr. У меня сейчас чуть лучший пример.
SS Anne