Информация об изменениях

Сообщение Re[25]: Как записать такое в современном C++? от 01.08.2024 13:18

Изменено 01.08.2024 14:16 kov_serg

Re[25]: Как записать такое в современном C++?
Здравствуйте, so5team, Вы писали:

S>В случае простых enum-ов оно не работает для типов, отличных от int.

S>В случае enum class оно не работает для типов, отличных от целочисленных, да еще и требует указывать дополнительный скоуп.
S>В общем, оно не работает. А я опять вляпался в известную субстанцию в попытках объяснить персонажам вроде вас очевидные вещи

Всё работает просто вы не так используете. В C++ принято всё через жопу делать
#include <iostream>
using namespace std;

enum E {
    name1,
    name2,
    name3
};

template<enum E e>const char* Es();
template<>const char* Es<name1>() { return "name1"; }
template<>const char* Es<name2>() { return "name2"; }
template<>const char* Es<name3>() { return "name3"; }

template<enum E e>double Ed();
template<>double Ed<name1>() { return 1; }
template<>double Ed<name2>() { return 0.5; }
template<>double Ed<name3>() { return 3.14; }

template<enum E e>bool Eс();
template<>bool Eс<name1>() { return true; }
template<>bool Eс<name2>() { return false; }
template<>bool Eс<name3>() { return false; }

static bool E_is_critical(enum E e) {
    switch(e) {
        case name1: return Eс<name1>();
        case name2: return Eс<name2>();
        case name3: return Eс<name3>();
    }
    throw;
}

template<enum E e>struct Eb;
template<>struct Eb<name1> {
    template<class T>
    static void run(T t) { t(); }
};
template<>struct Eb<name2> {
    template<class T>
    static void run(T t) { try { t(); } catch(...) {} }
};
template<>struct Eb<name3> {
    template<class T>
    static void run(T t) { try { t(); } catch(...) { cerr<<"ups\n"; } }
};

int main(int argc, char const *argv[]) {
    cout<<(Es<name1>())<<" "<<(Ed<name3>())<<endl;
    Eb<name3>::run([]{ throw 0; });
    return E_is_critical(name2);
}
Re[25]: Как записать такое в современном C++?
Здравствуйте, so5team, Вы писали:

S>В случае простых enum-ов оно не работает для типов, отличных от int.

S>В случае enum class оно не работает для типов, отличных от целочисленных, да еще и требует указывать дополнительный скоуп.
S>В общем, оно не работает. А я опять вляпался в известную субстанцию в попытках объяснить персонажам вроде вас очевидные вещи

Всё работает просто вы не так используете. В C++ принято всё через жопу делать
#include <iostream>
using namespace std;

enum E {
    name1,
    name2,
    name3
};

template <template<enum E> class M>
static auto E_get_value(enum E e) {
    switch(e) {
        case name1: return M<name1>::value();
        case name2: return M<name2>::value();
        case name3: return M<name3>::value();
    }
    throw;
}

template <template<enum E> class... M>
static auto E_forall(auto fn) {
    fn(M<name1>::value()...);
    fn(M<name2>::value()...);
    fn(M<name3>::value()...);
}

template<enum E e>const char* Es();
template<>const char* Es<name1>() { return "name1"; }
template<>const char* Es<name2>() { return "name2"; }
template<>const char* Es<name3>() { return "name3"; }

template<enum E e>double Ed();
template<>double Ed<name1>() { return 1; }
template<>double Ed<name2>() { return 0.5; }
template<>double Ed<name3>() { return 3.14; }

template<enum E e>struct Ed_values;
template<>struct Ed_values<name1> { static double value() { return Ed<name1>(); }};
template<>struct Ed_values<name2> { static double value() { return Ed<name2>(); }};
template<>struct Ed_values<name3> { static double value() { return Ed<name3>(); }};

template<enum E e>struct Es_values;
template<>struct Es_values<name1> { static const char* value() { return Es<name1>(); }};
template<>struct Es_values<name2> { static const char* value() { return Es<name2>(); }};
template<>struct Es_values<name3> { static const char* value() { return Es<name3>(); }};

template<enum E e>struct Eb;
template<>struct Eb<name1> {
    template<class T>
    static void run(T t) { t(); }
};
template<>struct Eb<name2> {
    template<class T>
    static void run(T t) { try { t(); } catch(...) {} }
};
template<>struct Eb<name3> {
    template<class T>
    static void run(T t) { try { t(); } catch(...) { cerr<<"catch\n"; } }
};

int main(int argc, char const *argv[]) {
    // не целые константы
    cout<<(Es<name3>())<<"="<<(Ed<name3>())<<endl;
    // получение значение
    enum E e=name2; cout<<E_get_value<Ed_values>(e)<<endl;
    // перебираем все значения
    E_forall<Es_values,Ed_values>([](const char* name,double value){
        cout<<name<<"="<<value<<endl;
    });
    // выбираем алгоритм по имени
    Eb<name3>::run([]{ throw 0; });
    return 0;
}

name3=3.14
0.5
name1=1
name2=0.5
name3=3.14
catch