Подтвердить что ты не робот

Как получить значение перечисления из типа перечисления?

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

В С++ 11 я могу сделать это:

#include <iostream>

namespace X {
    enum class  FOO { A,B };
}

template <typename T> void foo(T t) { 
    if (t == T::A) { std::cout << "A"; }
}

int main() {
    foo(X::FOO::A);
}

Важным моментом здесь является то, что шаблон foo не должен знать, в каком пространстве имен объявляется перечисление. Я мог бы также вызвать foo(Y::FOO::B) (при условии, что в пространстве имен Y есть enum class, называемый foo, с членами A и B).

Теперь возникает вопрос: как получить то же самое с простыми старыми перечислениями (и только с С++ 98)?

Это работает:

#include <iostream>

namespace X {
    enum FOO { A,B };
}

template <typename T> void foo(T t) { 
    if (t == X::A) { std::cout << "A"; }
}

int main() {
    foo(X::A);
}

но только потому, что foo знает, в каком пространстве имен объявляется перечисление. И это не будет работать для Y::FOO::B! (В С++ 11 он также работает, если я заменю строку на if (t == T::A) ..., даже с простым enum)

Есть ли способ заставить это работать в С++ 98/03 без ссылки на X в шаблоне явно?

Для полноты в С++ 98 этот

template <typename T> void foo(T t) { 
    if (t == T::A) { std::cout << "A"; }
}

приводит к

error: ‘A’ is not a member of ‘X::FOO’

PS: мне не разрешено изменять enum, и шаблон должен жить в другом пространстве имен, чем enum.

PPS: простой if (t == 0), вероятно, будет работать, но это то, что я хотел бы избежать

4b9b3361

Ответ 1

Чтобы добавить к ответ Никололя Боласа, вы можете взломать свой путь к решению, используя ADL:

namespace X {
    enum FOO { A,B };
    bool IsA(FOO t)
    {
        return t == A;
    }
}

template <typename T> void foo(T t) { 
    if (IsA(t)) { std::cout << "A\n"; }
    else{std::cout << "not A\n";}
}

Live Demo

Ответ 2

До С++ 11 не было возможности сказать "имя перечислителя в этом перечислении". Именно поэтому он был добавлен в С++ 11, даже для неперечисленных перечислений.