Если вы определяете operator <<
для C++ 11 enum class
, вы можете использовать его успешно с библиотекой модулей тестирования Boost.Ускорение теста с ошибками с перечисляемыми классами внутри пространств имен
Однако, если вы положили enum class
внутри namespace
, код Boost больше не компилируется.
Почему помещение enum class
внутри namespace
не работает? Он отлично работает с std::cout
в обоих направлениях, так что, конечно, это означает, что operator <<
верен?
Вот некоторые примеры кода демонстрирует проблему:
// g++ -std=c++11 -o test test.cpp -lboost_unit_test_framework
#include <iostream>
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE EnumExample
#include <boost/test/unit_test.hpp>
// Remove this namespace (and every "A::") and the code will compile
namespace A {
enum class Example {
One,
Two,
};
} // namespace A
std::ostream& operator<< (std::ostream& s, A::Example e)
{
switch (e) {
case A::Example::One: s << "Example::One"; break;
case A::Example::Two: s << "Example::Two"; break;
}
return s;
}
BOOST_AUTO_TEST_CASE(enum_example)
{
A::Example a = A::Example::One;
A::Example b = A::Example::Two;
// The following line works with or without the namespace
std::cout << a << std::endl;
// The following line does not work with the namespace - why?
BOOST_REQUIRE_EQUAL(a, b);
}
Ага, это объясняет это, спасибо! Поскольку я объявлял функцию в файле .hpp, мне пришлось поставить 'std :: ostream & operator << (std :: ostream & s, Example e);' в '.hpp' внутри пространства имен, затем в в .cpp', поставьте его как 'std :: ostream & A :: operator << (std :: ostream & s, A :: Example e)', чтобы он мог быть реализован за пределами пространства имен. Помещение реализации '.cpp' в другое пространство имен A {}' не работает. – Malvineous
@Malvineous Хорошая практика использования полнофункциональных имен при определении вещей в любом случае, если вы испортите декларации, это даст вам раннюю ошибку во время компиляции, а не связывание. – user657267