Вопрос в заголовке может показаться тривиальным, поэтому я лучше объясню некоторым кодом, что я хочу сделать...
В С++ 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)
, вероятно, будет работать, но это то, что я хотел бы избежать