Сообщение Re: Есть ли метод у класса - HasMethod - старая тема от 10.11.2019 19:24
Изменено 10.11.2019 22:09 rg45
Re: Есть ли метод у класса - HasMethod - старая тема
Здравствуйте, Molchalnik, Вы писали:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/b2e041f16b4f0df1
Собсно инструмент:
И пример использования:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/b2e041f16b4f0df1
Собсно инструмент:
#define ENABLE_HAS_METHOD(method) template <typename, typename, typename = void> struct has_method_##method : std::false_type {}; template <typename Obj, typename...Args> struct has_method_##method<Obj, std::tuple<Args...>, std::void_t<decltype(std::declval<Obj>().method(std::declval<Args>()...))>> : std::true_type {};
#define HAS_METHOD(method, class, ...) (has_method_##method<class, std::tuple<__VA_ARGS__>>::value)
И пример использования:
struct A
{
void foo();
void foo(int, double) const;
template <typename...Args>
void bar(Args&&...) const;
void baz() &;
void baz(const std::string&) const&;
void baz(const std::string&) && = delete;
void baz(int) &&;
};
ENABLE_HAS_METHOD(foo)
ENABLE_HAS_METHOD(bar)
ENABLE_HAS_METHOD(baz)
int main()
{
std::cout << std::boolalpha;
std::cout << "--- foo ---" << std::endl;
std::cout << HAS_METHOD(foo, const A) << std::endl; // false
std::cout << HAS_METHOD(foo, A) << std::endl; // true
std::cout << HAS_METHOD(foo, A, int, double) << std::endl; // true
std::cout << "--- bar ---" << std::endl;
std::cout << HAS_METHOD(bar, const A) << std::endl; // true
std::cout << HAS_METHOD(bar, A) << std::endl; // true
std::cout << HAS_METHOD(bar, A, double&, int) << std::endl; // true
std::cout << HAS_METHOD(bar, A, std::string, const std::string&, std::string&, std::string&) << std::endl; // true
std::cout << HAS_METHOD(bar, volatile A, int) << std::endl; // false
std::cout << "--- baz ---" << std::endl;
std::cout << HAS_METHOD(baz, A&) << std::endl; // true
std::cout << HAS_METHOD(baz, A&, std::string) << std::endl; // true
std::cout << HAS_METHOD(baz, const A&, std::string) << std::endl; // true
std::cout << HAS_METHOD(baz, A, int) << std::endl; // true
std::cout << HAS_METHOD(baz, const A&) << std::endl; // false
std::cout << HAS_METHOD(baz, A, std::string) << std::endl; // false
std::cout << HAS_METHOD(baz, A&&, std::string) << std::endl; // false
std::cout << HAS_METHOD(baz, const A&, int) << std::endl; // false
}
Re: Есть ли метод у класса - HasMethod - старая тема
Здравствуйте, Molchalnik, Вы писали:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/5e7c5dcd2b844e6b
Собсно инструмент:
И пример использования:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/5e7c5dcd2b844e6b
Собсно инструмент:
#define ENABLE_HAS_METHOD(method) template <typename, typename = void> struct has_method_##method : std::false_type {}; template <typename Obj, typename...Args> struct has_method_##method<std::tuple<Obj, Args...>, std::void_t<decltype(std::declval<Obj>().method(std::declval<Args>()...))>> : std::true_type {};
#define HAS_METHOD(method, ...) (has_method_##method<std::tuple<__VA_ARGS__>>::value)
И пример использования:
struct A
{
void foo();
void foo(int, double) const;
template <typename...Args>
void bar(Args&&...) const;
void baz() &;
void baz(const std::string&) const&;
void baz(const std::string&) && = delete;
void baz(int) &&;
};
ENABLE_HAS_METHOD(foo)
ENABLE_HAS_METHOD(bar)
ENABLE_HAS_METHOD(baz)
int main()
{
std::cout << std::boolalpha;
std::cout << "--- foo ---" << std::endl;
std::cout << HAS_METHOD(foo, const A) << std::endl; // false
std::cout << HAS_METHOD(foo, A) << std::endl; // true
std::cout << HAS_METHOD(foo, A, int, double) << std::endl; // true
std::cout << "--- bar ---" << std::endl;
std::cout << HAS_METHOD(bar, const A) << std::endl; // true
std::cout << HAS_METHOD(bar, A) << std::endl; // true
std::cout << HAS_METHOD(bar, A, double&, int) << std::endl; // true
std::cout << HAS_METHOD(bar, A, std::string, const std::string&, std::string&, std::string&) << std::endl; // true
std::cout << HAS_METHOD(bar, volatile A, int) << std::endl; // false
std::cout << "--- baz ---" << std::endl;
std::cout << HAS_METHOD(baz, A&) << std::endl; // true
std::cout << HAS_METHOD(baz, A&, std::string) << std::endl; // true
std::cout << HAS_METHOD(baz, const A&, std::string) << std::endl; // true
std::cout << HAS_METHOD(baz, A, int) << std::endl; // true
std::cout << HAS_METHOD(baz, const A&) << std::endl; // false
std::cout << HAS_METHOD(baz, A, std::string) << std::endl; // false
std::cout << HAS_METHOD(baz, A&&, std::string) << std::endl; // false
std::cout << HAS_METHOD(baz, const A&, int) << std::endl; // false
}