Làm thế nào để so sánh chữ ký của hai chức năng?


35

Có cách nào để kiểm tra xem hai hàm có cùng chữ ký không? Ví dụ:

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

Trong ví dụ này, funAfunBlà sự kết hợp duy nhất của các hàm sẽ trả về true.

Câu trả lời:


39

Về cơ bản bạn muốn kiểm tra xem hai loại hàm có giống nhau không:

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

Tôi sẽ không gọi đây là 'so sánh chữ ký', vì, nếu tôi nhớ chính xác, kiểu trả về không phải là một phần của chữ ký (vì nó không ảnh hưởng đến độ phân giải quá tải).


20
Một kiểu trả về không tham gia vào độ phân giải quá tải cho các con trỏ hàm và nó là một phần của chữ ký cho các mẫu hàm .
Davis Herring


14

Những người khác đã đề cập đến giải pháp sử dụng std::is_samedecltype.

Bây giờ để tổng quát hóa việc so sánh cho một số chữ ký hàm tùy ý, bạn có thể làm như sau

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

và so sánh nhiều chức năng như một

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

( Xem bản demo trực tiếp )


Hoặc để gõ ít hơn (nghĩa là không có decltype), hãy biến nó thành một hàm

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

và gọi đơn giản bằng cách

areSameFunctions(funA, funB, funC) 

( Xem bản demo trực tiếp )


3

Như một khả năng khác chưa được đề cập: bạn có thể sử dụng typeidtừ typeinfo==:

#include <typeinfo>

if(typeid(funA) != typeid(funB))
    std::cerr << "Types not the same" << std::endl;

GCC cho tôi error: non-constant condition for static assertion.
HolyBlackCat

1
@HolyBlackCat À, đây là RTTI. Không biết rằng những cái này không constexpr. Tôi có một ví dụ tốt hơn một chút bây giờ.
SS Anne
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.