2015-11-24 11 views
1

Если вы определяете 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); 
} 

ответ

1

Вам нужно определить оператор в пространстве имен, если вы хотите использовать ADL.

#include <iostream> 
#define BOOST_TEST_DYN_LINK 
#define BOOST_TEST_MODULE EnumExample 
#include <boost/test/unit_test.hpp> 

namespace A { 

enum class Example { 
    One, 
    Two, 
}; 


std::ostream& operator<< (std::ostream& s, Example e) 
{ 
    switch (e) { 
     case A::Example::One: s << "Example::One"; break; 
     case A::Example::Two: s << "Example::Two"; break; 
    } 
    return s; 
} 

} // namespace A 

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); 
} 
+0

Ага, это объясняет это, спасибо! Поскольку я объявлял функцию в файле .hpp, мне пришлось поставить 'std :: ostream & operator << (std :: ostream & s, Example e);' в '.hpp' внутри пространства имен, затем в в .cpp', поставьте его как 'std :: ostream & A :: operator << (std :: ostream & s, A :: Example e)', чтобы он мог быть реализован за пределами пространства имен. Помещение реализации '.cpp' в другое пространство имен A {}' не работает. – Malvineous

+0

@Malvineous Хорошая практика использования полнофункциональных имен при определении вещей в любом случае, если вы испортите декларации, это даст вам раннюю ошибку во время компиляции, а не связывание. – user657267