Сообщение Есть ли метод у класса - HasMethod - старая тема от 08.11.2019 22:11
Изменено 22.11.2019 22:27 Molchalnik
Есть ли метод у класса - HasMethod - старая тема
Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.
Upd. 10.11.2019 по совету so5team переделал первоначальный вариант на type_traits версии c++17. первоначальный вариант — под катом
начнём с простого — зададим конкретный метод
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.
Upd. 10.11.2019 по совету so5team переделал первоначальный вариант на type_traits версии c++17. первоначальный вариант — под катом
начнём с простого — зададим конкретный метод
развернуть | |
| |
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
#include <iostream>
#include <cstdio>
struct A {
void AaBbCcDd() {}
};
struct B {
const char * SomeFun(int i) { return "aa"; }
};
/// @brief создаёт структурку ClassName с помощью которого можно определить наличие метода FunName в заданном классе (класс задаётся как параметр шаблона)
/// @details пример:
/// HAS_METHOD_DEFINTION( HasPrintMethod, Print )
/// struct S { void Print() {} };
/// void main () {
/// bool exist = HasPrintMethod<S>::value;
/// }
/// @warning не работает, если в методе есть 2 перегрузки метода, наличие которого мы проверяем
#define HAS_METHOD_DEFINITION( ClassName, FunName ) template <typename T, typename = void> struct ClassName : public std::false_type {}; template <typename T > struct ClassName < T, std::void_t< decltype(&T::FunName) > > : public std::true_type {};
HAS_METHOD_DEFINITION( HasMethod, AaBbCcDd )
HAS_METHOD_DEFINITION( HasMethod2, SomeFun )
int main() {
printf("\n%u %u %u", HasMethod <A>::value, HasMethod <B>::value, HasMethod <int>::value );
printf("\n%u %u %u", HasMethod2<A>::value, HasMethod2<B>::value, HasMethod2<int>::value );
return 0;
}
Первоначальный вариант | |
начнём с простого — зададим конкретный метод
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
Теперь, задав один макрос, мы получаем структурку с заданным 1м параметром именем, позволяющую нам определить наличие у любого класса метода с заданным 2м параметром именем | |
Есть ли метод у класса - HasMethod - старая тема
Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.
Upd. 10.11.2019 по совету so5team переделал первоначальный вариант на type_traits версии c++17. первоначальный вариант — под катом
начнём с простого — зададим конкретный метод
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
А вот вариант от rg45, который учитывает аргументы функции
Иногда он будет много полезнее моего, особенно в случае наличия перегруженных функций.
Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.
Upd. 10.11.2019 по совету so5team переделал первоначальный вариант на type_traits версии c++17. первоначальный вариант — под катом
начнём с простого — зададим конкретный метод
развернуть | |
| |
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
#include <iostream>
#include <cstdio>
struct A {
void AaBbCcDd() {}
};
struct B {
const char * SomeFun(int i) { return "aa"; }
};
/// @brief создаёт структурку ClassName с помощью которого можно определить наличие метода FunName в заданном классе (класс задаётся как параметр шаблона)
/// @details пример:
/// HAS_METHOD_DEFINTION( HasPrintMethod, Print )
/// struct S { void Print() {} };
/// void main () {
/// bool exist = HasPrintMethod<S>::value;
/// }
/// @warning не работает, если в методе есть 2 перегрузки метода, наличие которого мы проверяем
#define HAS_METHOD_DEFINITION( ClassName, FunName ) \
template <typename T, typename = void> struct ClassName : public std::false_type {}; \
template <typename T > struct ClassName < T, std::void_t< decltype(&T::FunName) > > : public std::true_type {};
HAS_METHOD_DEFINITION( HasMethod, AaBbCcDd )
HAS_METHOD_DEFINITION( HasMethod2, SomeFun )
int main() {
printf("\n%u %u %u", HasMethod <A>::value, HasMethod <B>::value, HasMethod <int>::value );
printf("\n%u %u %u", HasMethod2<A>::value, HasMethod2<B>::value, HasMethod2<int>::value );
return 0;
}
А вот вариант от rg45, который учитывает аргументы функции
Иногда он будет много полезнее моего, особенно в случае наличия перегруженных функций.
Вариант rg45, реагирующий только на функцию с точно совпадающими аргументами | |
| |
Первоначальный вариант | |
начнём с простого — зададим конкретный метод
Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
Теперь, задав один макрос, мы получаем структурку с заданным 1м параметром именем, позволяющую нам определить наличие у любого класса метода с заданным 2м параметром именем | |