Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 08.11.19 22:11
Оценка:
Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.

Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.

Upd. 10.11.2019 по совету so5team переделал первоначальный вариант на type_traits версии c++17. первоначальный вариант — под катом

начнём с простого — зададим конкретный метод
  развернуть
struct A {
  //const char * AaBbCcDd(int i) { return "aa"; }
  void AaBbCcDd() {}
};
struct B {};



template <typename T, typename = void>
struct  HasMethod : public std::false_type {};
template <typename T >
struct HasMethod < T, std::void_t< decltype(&T::AaBbCcDd) > > : public std::true_type {};


int main() {
    printf("\n%u %u %u", HasMethod<A>::value, HasMethod<B>::value, HasMethod<int>::value );
    return 0;    
}

Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
#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, реагирующий только на функцию с точно совпадающими аргументами
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>

#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( int, char, long) {} };
///           struct B { void NotPrint() {} };
///           void main () {
///             bool exist;
///             exist = HasPrintMethod<S, int, char, long>::value; // exist = 1
///             exist = HasPrintMethod<S, int, char>::value;       // exist = 0
///             exist = HasPrintMethod<B, int, char, long>::value; // exist = 0
///           }
/// @author rg45 aka Сергей Романченко в оформлении Molchalnik
/// @warning не работает, если в методе есть 2 перегрузки метода, наличие которого мы проверяем
#define HAS_METHOD_DEFINITION( ClassName, FunName )  \
    namespace curicios_hasmethod_namespace_ck9fs98 { \
    template <typename, typename = void>             \
    struct ClassName##_Helper : std::false_type {}; \
                                                     \
    template <typename Obj, typename...Args>             \
    struct ClassName##_Helper<std::tuple<Obj, Args...>, \
        std::void_t<decltype(std::declval<Obj>().FunName(std::declval<Args>()...))>> : std::true_type {}; \
    }  \
    template <typename Obj, typename...Args> using ClassName = curicios_hasmethod_namespace_ck9fs98::ClassName##_Helper<std::tuple<Obj, Args...> >; \
    
        

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, int>::value, HasMethod2<B, int>::value, HasMethod2<int, int>::value );
    return 0;    
}


  Первоначальный вариант
начнём с простого — зададим конкретный метод
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>


struct A {
  //const char * AaBbCcDd(int i) { return "aa"; }
  void AaBbCcDd() {}
};

struct B {};


template <typename T> struct HasMethod {
 private:
  struct HasMethodHelperFalse {
    static constexpr const bool value = 0;
  };

  template <class T2, decltype(&T2::AaBbCcDd) U = &T2::AaBbCcDd > struct HasMethodHelperTrue {
    static constexpr const bool value = 1;
  };

  HasMethodHelperFalse static constexpr detect(...) { return HasMethodHelperFalse(); }

  template <typename T2> HasMethodHelperTrue<T2> static constexpr detect( T2 * ) { return HasMethodHelperTrue<T2>();  }

 public:
  static constexpr const bool value = decltype(     detect(   static_cast<T*>( nullptr )   )     ):: value;
};


int main() {
    printf("\n%u %u %u", HasMethod<A>::value, HasMethod<B>::value, HasMethod<int>::value );
    return 0;    
}


Но если надо будет сделать то же для другого метода, всё придётся переписывать. А кода много. Неудобно. Что делать? Нетрушные методы — макросы — помогут нам
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>


struct A {
  const char * SomeFun(int i) { return "aa"; }
  void AaBbCcDd() {}
};

struct B {};

/// @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> struct ClassName { \
 private: \
  struct HasMethodHelperFalse { \
    static constexpr const bool value = 0; \
  };\
\
  template <class T2, decltype(&T2::FunName) U = &T2:: FunName > struct HasMethodHelperTrue { \
    static constexpr const bool value = 1; \
  }; \
\
  HasMethodHelperFalse static constexpr detect(...) { return HasMethodHelperFalse(); } \
\
  template <typename T2> HasMethodHelperTrue<T2> static constexpr detect( T2 * ) { return HasMethodHelperTrue<T2>();  } \
\
 public: \
  static constexpr const bool value = decltype(     detect(   static_cast<T*>( nullptr )   )     ):: value;\
};

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м параметром именем
Отредактировано 22.11.2019 22:27 Molchalnik . Предыдущая версия . Еще …
Отредактировано 10.11.2019 9:20 Molchalnik . Предыдущая версия .
Отредактировано 09.11.2019 11:25 Molchalnik . Предыдущая версия .
Отредактировано 08.11.2019 22:17 Molchalnik . Предыдущая версия .
sfinae has method определить есть ли метод у класса
Re: Есть ли метод у класса - HasMethod - старая тема
От: niXman Ниоткуда https://github.com/niXman
Дата: 09.11.19 23:36
Оценка:
а можно просто заюзать boost.tti
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 10.11.19 07:40
Оценка: +1 -1
Здравствуйте, niXman, Вы писали:

X>а можно просто заюзать boost.tti


Буст тяжелая библиотека, её не имеет смысла тащить из-за одной фичи, только если есть рассчёт на её плотное использование.
Re: Есть ли метод у класса - HasMethod - старая тема
От: so5team https://stiffstream.com
Дата: 10.11.19 07:54
Оценка: 2 (1)
Здравствуйте, Molchalnik, Вы писали:

M>начнём с простого — зададим конкретный метод


Гораздо более простой способ описан на cppreference. Для C++17 разработчику ничего и не нужно делать, std::void_t уже в наличии. Для C++14 void_t нужно будет определить самостоятельно, но там же на cppreference показано как это сделать.
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 10.11.19 09:21
Оценка:
Здравствуйте, so5team, Вы писали:

S>Гораздо более простой способ описан на cppreference.


Вы правы, коллега, моя олдфажность меня подводит. Поправил стартовый топик
Re: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 10.11.19 09:27
Оценка: +3
Здравствуйте, Molchalnik, Вы писали:

M>Теперь, задав один макрос, мы получаем структурку с заданным 1м параметром именем, позволяющую нам определить наличие у любого класса метода с заданным 2м параметром именем


Из-за того, через какую задницу в "современном C++" приходится делать подобные вещи, и возникают сомнения в психическом здоровье главных идеологов языка, прямо пропагандирующих такой подход. По-хорошему, все это должно быть в ядре, а шаблоны должны использоваться для того, для чего были придуманы изначально.

Неудивительно, что у С++ все больше противников. Ну какое мнение об адекватности языка и его парадигм может возникнуть у человека, не являющегося фанатом C++, при виде подобного?
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 10.11.19 09:53
Оценка: +1 :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Неудивительно, что у С++ все больше противников. Ну какое мнение об адекватности языка и его парадигм может возникнуть у человека, не являющегося фанатом C++, при виде подобного?


Не нравится этот рубанок — стругай другим. Оценка же рубанков весьма необъективна. Плюсы на данный момент — универсальный язык, который может всё, но из-за попытки натянуть сову на глобус с поддержкой Legacy содержащий всё больше и больше костылей. Рано или поздно он либо получит тег вроде version 23 { }, в рамках которого зашлёт всё легаси лесом и устроит новые продуманные синтаксис и правила. Либо кто-то предоставит язык, с возможностями плюсов, но без legacy. Пока другого универсального языка нет, а есть нишевые — которые теснят плюсы, но теснят скопом, все на одного. Никакой замены или альтернативы плюсам нет.
Re: Есть ли метод у класса - HasMethod - старая тема
От: Videoman Россия https://hts.tv/
Дата: 10.11.19 10:40
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.


У меня в библиотеках кое-где используется такой вариант:
#include <type_traits>

template <typename Type>
struct has_print_method
{
    template <typename Other> static std::true_type test(decltype(std::declval<Other>().Print(0), int()));
    template <typename Other> static std::false_type test(...);
    static constexpr bool value = decltype(test<Type>(0))::value;
};

struct A
{  
    void Print(int) {};
    void Print(long) {};
};

struct B
{  
};

static_assert(has_print_method<A>::value);
// static_assert(has_print_method<B>::value); // Не компилируется

Вроде, на перегрузки ему пофигу.
Re: Есть ли метод у класса - HasMethod - старая тема
От: prog123 Европа  
Дата: 10.11.19 12:20
Оценка: 6 (1) :)
Здравствуйте, Molchalnik, Вы писали:

M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.


Тут уже упомянули cppreference, но ссылку дали не туда. Вот, насколько я понял, прямо то что нужно. Ну и пример оттуда, немного модифицированный

#include <type_traits>

class A {
public:
    void member1() { }
    void member2() { }
};

class B
{
};

template<typename T>
using HasMember1 = std::is_member_function_pointer<decltype(&T::member1)>;
template<typename T>
using HasMember2 = std::is_member_function_pointer<decltype(&T::member2)>;

int main()
{
    static_assert(std::is_member_function_pointer_v<decltype(&A::member1)>,
                  "A::membe1r is not a member function.");
    static_assert(std::is_member_function_pointer_v<decltype(&A::member2)>,
                  "A::member2 is not a member function.");
    static_assert(HasMember1<A>::value);
    static_assert(HasMember2<A>::value);
    //static_assert(HasMember1<B>::value);   // uncommment and get compilation error
    //static_assert(HasMember1<int>::valu);  // the same as above
    return 0;
}
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: niXman Ниоткуда https://github.com/niXman
Дата: 10.11.19 12:35
Оценка: +3
Здравствуйте, Molchalnik, Вы писали:

M>Буст тяжелая библиотека, её не имеет смысла тащить из-за одной фичи, только если есть рассчёт на её плотное использование.


никогда не понимал этого... что значит тащить? вы исходники на дискете распростанняете?
большую часть моей карьеры boost используется везде. даже на своей домашней машине я устанавливаю boost сразу после компилятора...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: niXman Ниоткуда https://github.com/niXman
Дата: 10.11.19 12:37
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>... Рано или поздно он либо получит тег вроде version 23 { }, в рамках которого зашлёт всё легаси лесом и устроит новые продуманные синтаксис и правила. Либо кто-то предоставит язык, с возможностями плюсов, но без legacy.


@here кстати, а разве такого никто до сих пор еще не сделал? никто не встречал ничего подобного?
думаю, на основе шланга сделать это было бы не очень сложно. (в смысле — сложно, но не настолько, как писать еще одного "убийцу плюсов")
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 10.11.2019 12:38 niXman . Предыдущая версия .
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 10.11.19 12:45
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Не нравится этот рубанок — стругай другим.


Сам-то рубанок как раз нравится. А вот ситуация, из-за которой в рубанке можно быстро и надежно закрепить лишь пару-тройку самых основных лезвий, а все остальные лезвия приходится приматывать проволокой и придерживать при работе, и производитель рубанка объявляет такой подход совершенно нормальным — не нравится категорически.

M>Плюсы на данный момент — универсальный язык, который может всё


Кто бы спорил.

M>но из-за попытки натянуть сову на глобус с поддержкой Legacy содержащий всё больше и больше костылей.


Поддержка legacy — совершенно отдельный вопрос. Я о том, что информацию о типах и возможности условной компиляции за пределами примитивных числовых выражений должно предоставлять ядро языка. Ситуация, в которой для этого необходимо создавать неестественные конструкции из возможностей, предназначенных совсем для другого, ненормальна по определению. И то, что люди, стоящие во главе разработки языка, явно ее поддерживают, отнюдь не делает им чести.
Re: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 10.11.19 19:24
Оценка: 2 (1) +1
Здравствуйте, Molchalnik, Вы писали:

M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.


Ну и я свои пять копеек вставлю

В этом варианте проверяется возможность обращения к методу с заданным набором типов ФАКТИЧЕСКИХ параметров. Учитывается совместимость по const/volatile и по разновидностям ссылок — как параметров, так и самого объекта.

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
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 11.11.2019 8:49 rg45 . Предыдущая версия . Еще …
Отредактировано 11.11.2019 8:26 rg45 . Предыдущая версия .
Отредактировано 11.11.2019 8:23 rg45 . Предыдущая версия .
Отредактировано 10.11.2019 23:40 rg45 . Предыдущая версия .
Отредактировано 10.11.2019 22:09 rg45 . Предыдущая версия .
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 07:54
Оценка: +1
Здравствуйте, prog123, Вы писали:

P>
P>    //static_assert(HasMember1<B>::value);   // uncommment and get compilation error
P>    //static_assert(HasMember1<int>::valuе);  // the same as above
P>



Беда в том, что эти выражения и без static_assert приводят к ошибке. А хотелось бы, чтоб они давали false, так, чтоб к ним можно было применить логическое отрицание и использовать в SFINAE, например.

templame <typename T>
std::enable_if_t<HasMemeber1<T>::value> foo(const T& t) { t.Member1(); }

templame <typename T>
std::enable_if_t<!HasMemeber1<T>::value> foo(const T& t) { process_common_case(t); }
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 11.11.2019 8:09 rg45 . Предыдущая версия . Еще …
Отредактировано 11.11.2019 8:07 rg45 . Предыдущая версия .
Отредактировано 11.11.2019 8:05 rg45 . Предыдущая версия .
Re: Есть ли метод у класса - HasMethod - старая тема
От: smbdnew  
Дата: 11.11.19 08:19
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.


M>Решил обновить вопрос. Не претендую на новизну и оригинальность, наверняка кто-то где-то уже сделал так или почти так. Но на нашем форуме не нашёл, поэтому счёл уместным поднять вопрос снова.


а компилятор то какой ? msvc умеет так
class Class {
public:
    void Method();
};

int main() {
    __if_exists(Class::Method) {
        print("Class::Method exists");
    }

    __if_not_exists(Class::Method1) {
        print("Class::Method1 not exists");
    }
}
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 08:37
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>а компилятор то какой ?


А хочется, чтоб было переносимо

  S>msvc умеет так
S>
S>class Class {
S>public:
S>    void Method();
S>};

S>int main() {
S>    __if_exists(Class::Method) {
S>        print("Class::Method exists");
S>    }

S>    __if_not_exists(Class::Method1) {
S>        print("Class::Method1 not exists");
S>    }
S>}
S>


А если нужно проверить не только имя, но и совместимость по количеству и типам параметров?
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 11.11.2019 8:39 rg45 . Предыдущая версия . Еще …
Отредактировано 11.11.2019 8:38 rg45 . Предыдущая версия .
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 09:20
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>msvc умеет так


Только при непосредственной квалификации имени метода именем класса. Проверить наличие метода у объекта, доступность виртуальной функции и т.п. уже не получится, хотя все это легко разрешимо на этапе компиляции.

Я ж говорю — есть только костыли, да и те кривые.
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 09:25
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я ж говорю — есть только костыли, да и те кривые.


Есть возможность проверить допустимость выражения любой сложности на этапе компиляции. Здесь
Автор: rg45
Дата: 10.11.19
черновой набросок, далекий от совершенства, но дающий некоторое представление о возможных подходах.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 09:33
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здесь
Автор: rg45
Дата: 10.11.19
черновой набросок, далекий от совершенства, но дающий некоторое представление о возможных подходах.


Я выше уже писал, что возможность-то есть, но реализована она может быть лишь крайне извращенными (по отношению к основной парадигме языка). Да, окончательный синтаксис с макросом выглядит более-менее пристойно, но внутри него — откровенный ужас, разумного оправдания которому не существует. Это все от безысходности, которая активно поддерживается верхушкой разработчиков стандарта.
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: Ops Россия  
Дата: 11.11.19 09:39
Оценка: +1
Здравствуйте, Molchalnik, Вы писали:

M>Буст тяжелая библиотека, её не имеет смысла тащить из-за одной фичи, только если есть рассчёт на её плотное использование.


Буст это не библиотека, а набор библиотек. Большинство очень даже легкие, не генерируют кода на неиспользуемые собственные фичи, и их можно использовать отдельно, не таща ничего лишнего. А для рабочего окружения разработчика буст и целиком не сказать чтобы тяжелый.
Вот этот подход, что буст "тяжелый" — он от непонимания, что это такое и как устроено.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[5]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 09:45
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я выше уже писал, что возможность-то есть, но реализована она может быть лишь крайне извращенными (по отношению к основной парадигме языка). Да, окончательный синтаксис с макросом выглядит более-менее пристойно, но внутри него — откровенный ужас, разумного оправдания которому не существует. Это все от безысходности, которая активно поддерживается верхушкой разработчиков стандарта.


А как понять, где ужас, где не ужас, где извращение, где не извращение? Это ж всего лишь твои эмоции и субъективные оценки. У меня они тоже есть, но существенно отличаются от твоих.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Есть ли метод у класса - HasMethod - старая тема
От: night beast СССР  
Дата: 11.11.19 10:02
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

R>>Здесь
Автор: rg45
Дата: 10.11.19
черновой набросок, далекий от совершенства, но дающий некоторое представление о возможных подходах.


ЕМ>Я выше уже писал, что возможность-то есть, но реализована она может быть лишь крайне извращенными (по отношению к основной парадигме языка). Да, окончательный синтаксис с макросом выглядит более-менее пристойно, но внутри него — откровенный ужас, разумного оправдания которому не существует. Это все от безысходности, которая активно поддерживается верхушкой разработчиков стандарта.


это из-за отсутствия рефлексии, работы по добавлению которою в стандарт ведутся верхушкой разработчиков стандарта.
Re[6]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 10:23
Оценка:
Здравствуйте, rg45, Вы писали:

R>А как понять, где ужас, где не ужас, где извращение, где не извращение?


Да хотя бы по тому, что возможность применения шаблонов для анализа типов и их взаимоотношений в C++ была не заложена, а открыта (на это уже много раз указывали). То есть, задача у шаблонов была совершенно другой, и она вполне себе укладывается в парадигму языка. А когда обнаружили эти дополнительные возможности, пусть и реализуемые через явную задницу, и энтузиасты вроде Александреску, получающие главный кайф не от логичности и продуманности набора средств, а от озарений типа "ого, а ведь можно еще и так!", наработали вариантов их применения, было постановлено: "если это можно сделать на шаблонах — значит, надо делать на них, и нечего усложнять ядро".

Там, где достаточно простые задачи требуют совершенно излишней эквилибристики, да еще и чуждой самой сути задачи, везде ужас и извращение.
Re[6]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 10:26
Оценка:
Здравствуйте, night beast, Вы писали:

NB>это из-за отсутствия рефлексии


Рефлексия — это уже следующая ступень. Она не является необходимой для получения на этапе компиляции всей информации о типах, которой уже располагает компилятор.
Re[7]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 12:47
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я выше уже писал, что возможность-то есть, но реализована она может быть лишь крайне извращенными (по отношению к основной парадигме языка). Да, окончательный синтаксис с макросом выглядит более-менее пристойно, но внутри него — откровенный ужас, разумного оправдания которому не существует. Это все от безысходности, которая активно поддерживается верхушкой разработчиков стандарта.


R>>А как понять, где ужас, где не ужас, где извращение, где не извращение?


ЕМ>Да хотя бы по тому, что возможность применения шаблонов для анализа типов и их взаимоотношений в C++ была не заложена, а открыта (на это уже много раз указывали).


Гм, тогда почему "окончательный синтаксис с макросом" — это не ужас? Это ведь такое же применение шаблонов для анализа типов, да еще и с макросами. Что-то ты сам себе противоречишь.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[8]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 13:00
Оценка:
Здравствуйте, rg45, Вы писали:

R>Гм, тогда почему "окончательный синтаксис с макросом" — это не ужас?


Я имел в виду исключительно конструкцию, где макрос применяется, а не само его определение (которое, разумеется, есть ужас). Она, конечно, тоже выглядит очень коряво, но для ее понимания хотя бы не требуется вдумчиво вникать в тонкости обработки шаблонов компилятором (которые, повторю, начали применяться по чистой случайности).
Re[9]: Есть ли метод у класса - HasMethod - старая тема
От: rg45 СССР  
Дата: 11.11.19 13:18
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Я выше уже писал, что возможность-то есть, но реализована она может быть лишь крайне извращенными (по отношению к основной парадигме языка). Да, окончательный синтаксис с макросом выглядит более-менее пристойно, но внутри него — откровенный ужас, разумного оправдания которому не существует. Это все от безысходности, которая активно поддерживается верхушкой разработчиков стандарта.


R>А как понять, где ужас, где не ужас, где извращение, где не извращение?


ЕМ>Да хотя бы по тому, что возможность применения шаблонов для анализа типов и их взаимоотношений в C++ была не заложена, а открыта (на это уже много раз указывали).


R>Гм, тогда почему "окончательный синтаксис с макросом" — это не ужас?


ЕМ>Я имел в виду исключительно конструкцию, где макрос применяется, а не само его определение (которое, разумеется, есть ужас).


Я тоже имел в виду исключительно конструкцию, где макрос применяется. Применение этого макроса — это такое же использование шаблонов для анализа типов. Однако в одном месте это ужас, по-твоему, а в другом, не ужас, почему-то
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 11.11.2019 13:51 rg45 . Предыдущая версия . Еще …
Отредактировано 11.11.2019 13:19 rg45 . Предыдущая версия .
Re[10]: Есть ли метод у класса - HasMethod - старая тема
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.11.19 14:11
Оценка:
Здравствуйте, rg45, Вы писали:

R>Применение этого макроса — это такое же использование шаблонов для анализа типов.


Ну хорошо, конструкцию с применением макроса можно считать ужасом второго порядка. Я имел в виду, что человеку, не вникавшему в побочные эффекты использования шаблонов, требуются лишь минимальные умственные усилия, чтобы понять смысл этой конструкции и способы ее использования.

Можно было бы даже сказать, что для успешного использования подобных конструкций, импортированных из библиотек, вовсе не обязательно вникать в их реализации. Но мы же знаем, что это не так — при некоторых ошибках компилятор вывалит кашу из сообщений, разобраться в которой бывает непросто даже автору, не говоря уже о пользователе. И это тоже ужас.
Re[4]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 11.11.19 22:19
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Здравствуйте, Molchalnik, Вы писали:


M>>Буст тяжелая библиотека, её не имеет смысла тащить из-за одной фичи, только если есть рассчёт на её плотное использование.


Ops>Буст это не библиотека, а набор библиотек. Большинство очень даже легкие, не генерируют кода на неиспользуемые собственные фичи, и их можно использовать отдельно, не таща ничего лишнего. А для рабочего окружения разработчика буст и целиком не сказать чтобы тяжелый.

Ops>Вот этот подход, что буст "тяжелый" — он от непонимания, что это такое и как устроено.

Я прекрасно понимаю, как работают шаблоны, более того, пытался вырвать из буста куски и скомпилить их. Это тот ещё челлендж. А если всё целиком подключать, то даже если оптимизатор выкинет, вы всё равно это будете компилировать очень долго. Время компиляции, даже если шаблон не инстанцируется или класс не используется, всё равно значительно растёт.
Re[5]: Есть ли метод у класса - HasMethod - старая тема
От: Ops Россия  
Дата: 12.11.19 23:35
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Я прекрасно понимаю, как работают шаблоны, более того, пытался вырвать из буста куски и скомпилить их. Это тот ещё челлендж. А если всё целиком подключать, то даже если оптимизатор выкинет, вы всё равно это будете компилировать очень долго. Время компиляции, даже если шаблон не инстанцируется или класс не используется, всё равно значительно растёт.


Вот именно, судишь обо всем скопом. А на деле, надо смотреть конкретный случай, а не отказываться "от буста", будто это такой монолит. Какие-то библиотеки или их части, без "вырывания", как есть, могут быть вполне легкими, никто же не заставляет подключать все. Даже отдельные библиотеки часто не монолитны, и один их функционал может не требовать другой; а со слабой связностью там все достаточно хорошо обстоит. Ну а то что оно у тебя где-то на диске лежит — так ведь каши не просит.
Я могу понять, когда пишут, что такая-то библиотека или функционал не подходит по таким-то причинам (не то что хотелось, долгая компиляция, и т.п.), но когда обобщают на все, это уже перебор.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re: Есть ли метод у класса - HasMethod - старая тема
От: ViTech  
Дата: 19.11.19 14:00
Оценка:
Ещё можно стащить реализацию из std::experimental::is_detected. А в C++20 определять наличие методов и типов в классе можно будет с помощью концептов.
Пока сам не сделаешь...
Re[2]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 22.11.19 22:29
Оценка: 9 (1)
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Molchalnik, Вы писали:


M>>Искал на нашем форуме SFINAE фишку по определению наличия класса в методе — нашёл только очень старую тему, написанную по старому стандарту, и которую крайне трудно адаптировать, потому что проще для каждого нового метода написать с нуля.


R>Ну и я свои пять копеек вставлю


Добавил в заглавный пост. поправил текст на более единообразный. поставил плюсик.

Потом, возможно, и другие варианты добавлю в заглавный, ежели будет время.

Эх, а мне плюсик за систематизацию ответов по классической теме никто не поставил
Отредактировано 22.11.2019 22:31 Molchalnik . Предыдущая версия .
Re[3]: Есть ли метод у класса - HasMethod - старая тема
От: Erop Россия  
Дата: 03.12.19 06:55
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Либо кто-то предоставит язык, с возможностями плюсов, но без legacy. Пока другого универсального языка нет, а есть нишевые — которые теснят плюсы, но теснят скопом, все на одного. Никакой замены или альтернативы плюсам нет.


Пока таких предложили кучу. От D до Go
Скорее всего будет появляться всё больше задач, где востребованы другие свойства стати языков, чем те, коими славны плюсы, и С++ станет таки же нишевым, как сейчас стал С, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Есть ли метод у класса - HasMethod - старая тема
От: Molchalnik  
Дата: 04.12.19 19:00
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Molchalnik, Вы писали:


M>>Либо кто-то предоставит язык, с возможностями плюсов, но без legacy. Пока другого универсального языка нет, а есть нишевые — которые теснят плюсы, но теснят скопом, все на одного. Никакой замены или альтернативы плюсам нет.


E>Пока таких предложили кучу. От D до Go


Плюсы пока мощнее всех, за счёт этого и держатся. им бы тэг типа version 23 {} помог сильно
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.