Сообщение Re: Есть ли метод у класса - HasMethod - старая тема от 10.11.2019 19:24
Изменено 10.11.2019 23:40 rg45
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
}
Re: Есть ли метод у класса - HasMethod - старая тема
Здравствуйте, Molchalnik, Вы писали:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/9342a5dfe9074fa7
Собсно инструмент:
И пример использования:
M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.
Ну и я свои пять копеек вставлю
http://coliru.stacked-crooked.com/a/9342a5dfe9074fa7
Собсно инструмент:
#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;
#define CHECK(cond) (std::cout << #cond << ": " << cond << std::endl)
std::cout << "--- foo ---" << std::endl;
CHECK(HAS_METHOD(foo, const A)); // false
CHECK(HAS_METHOD(foo, A)); // true
CHECK(HAS_METHOD(foo, A, int, double)); // true
std::cout << "--- bar ---" << std::endl;
CHECK(HAS_METHOD(bar, const A)); // true
CHECK(HAS_METHOD(bar, A)); // true
CHECK(HAS_METHOD(bar, A, double&, int)); // true
CHECK(HAS_METHOD(bar, A, std::string, const std::string&, std::string&, std::string&)); // true
CHECK(HAS_METHOD(bar, volatile A, int)); // false
std::cout << "--- baz ---" << std::endl;
CHECK(HAS_METHOD(baz, A&)); // true
CHECK(HAS_METHOD(baz, A&, std::string)); // true
CHECK(HAS_METHOD(baz, const A&, std::string)); // true
CHECK(HAS_METHOD(baz, A, int)); // true
CHECK(HAS_METHOD(baz, const A&)); // false
CHECK(HAS_METHOD(baz, A, std::string)); // false
CHECK(HAS_METHOD(baz, A&&, std::string)); // false
CHECK(HAS_METHOD(baz, const A&, int)); // false
}