Як порівняти підпис двох функцій?


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)>

Я б не називав це «порівнянням підписів», оскільки, якщо я добре пам’ятаю, тип повернення не є частиною підпису (тому що це не впливає на дозвіл перевантаження).


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)>

( Дивіться демо-версію )


Або для менш введеного тексту (тобто без decltype), зробіть це як функцію

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

і телефонувати просто мимо

areSameFunctions(funA, funB, funC) 

( Дивіться демо-версію )


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. Зараз у мене є трохи кращий приклад.
СС Енн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.