Bagaimana cara membandingkan tanda tangan dari dua fungsi?

35

Apakah ada cara untuk memeriksa apakah dua fungsi memiliki tanda tangan yang sama? Sebagai contoh:

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

Dalam contoh ini, funAdan funBmerupakan satu-satunya kombinasi fungsi yang harus kembali true.

Stefano Pittalis
sumber

Jawaban:

39

Pada dasarnya Anda ingin memeriksa apakah jenis dua fungsi sama:

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

Saya tidak akan menyebut ini 'membandingkan tanda tangan', karena, jika saya ingat dengan benar, tipe pengembalian bukan bagian dari tanda tangan (karena tidak mempengaruhi resolusi kelebihan beban).

HolyBlackCat
sumber
20
Tipe kembali tidak berpartisipasi dalam resolusi kelebihan untuk pointer fungsi , dan itu adalah bagian dari tanda tangan untuk templat fungsi .
Davis Herring
15

Anda dapat memeriksa jenis fungsi dengan decltypedan std::is_same. misalnya

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

HIDUP

songyuanyao
sumber
14

Orang lain telah menyebutkan solusi menggunakan std::is_samedan decltype.

Sekarang untuk menggeneralisasi perbandingan untuk sejumlah tanda tangan fungsi sewenang-wenang, Anda dapat melakukan hal berikut

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

dan bandingkan sebanyak mungkin fungsi

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

( Lihat Demo Langsung )


Atau untuk kurang mengetik (mis. Tanpa decltype), jadikan itu sebagai fungsi

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

dan telepon hanya dengan

areSameFunctions(funA, funB, funC) 

( Lihat Demo Langsung )

JeJo
sumber
3

Sebagai kemungkinan lain yang belum disebutkan: Anda dapat menggunakan typeiddari typeinfodan ==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;
SS Anne
sumber
GCC memberi saya error: non-constant condition for static assertion.
HolyBlackCat
1
@HolyBlackCat Ah, ini RTTI. Tidak tahu ini bukan constexpr. Saya punya contoh yang sedikit lebih baik sekarang.
SS Anne