2012-06-11 3 views
7

인 경우 BOOST_CHECK_EQUAL (쌍, 쌍)을 시도하면 gcc는 쌍을위한 스트림 연산자를 찾지 않습니다. 재미있는 점은 std :: out이 연산자를 찾는다는 것입니다.BOOST_CHECK_EQUAL 쌍이 <int, int>이고 사용자 지정 연산자가 <<

ostream& operator<<(ostream& s, const pair<int,int>& p) { 
    s << '<' << p.first << ',' << p.second << '>'; 
    return s; 
} 


BOOST_AUTO_TEST_CASE(works) 
{ 
    pair<int,int> expected(5, 5); 
    pair<int,int> actual (5, 5); 
    std::cout << expected << std::endl; 
    std::cout << actual << std::endl; 
    BOOST_CHECK(actual == expected); 
} 

BOOST_AUTO_TEST_CASE(no_work) 
{ 
    pair<int,int> expected(5, 5); 
    pair<int,int> actual (5, 5); 
    BOOST_CHECK_EQUAL(actual, expected); 
} 

이 나던 오류 컴파일 :

... instantiated from here 
../boost-atp/release/include/boost/test/test_tools.hpp:326:9: error: no match for ‘operator<<’ in ‘ostr << t’ 
+0

사용자 정의 유형에 대한 자신의 인쇄를 정의의 * ​​새로운 * 방법이 여기에 설명 : https://stackoverflow.com/a/44810846/1617295, 그리고 [이는 그 코드는 시작해야한다 공식 문서] (http://www.boost.org/doc/libs/1_66_0/libs/test/doc/html/boost_test/test_output/test_tools_support_for_logging/testing_tool_output_disable.html)를 참조하십시오. – Raffi

+0

@ 라피 (Raffi)이 질문은이 사본이 중복 된 것처럼 보입니다. 어쩌면 그것을 중복으로 표시하고 여기에 답을 옮겨서 사용자가 점프하지 않도록 할 수 있습니까? 나는 그것을 받아 들일 수있다. 감사! – nishantjr

답변

7

operator<<stdRemus's answer과 같이 넣는 것은 C++ 14 초안 (N4296 섹션 : 17.6.4.2.1)에서 정의되지 않은 동작입니다. 부스트는 후크 (used by this answer)를 제공하고 당신은 쓸 수 있습니다 :

namespace boost 
{ 
    namespace test_tools 
    { 
     template<typename T,typename U> 
     struct print_log_value<std::pair<T, U> > 
     { 
      void operator()(std::ostream& os, std::pair<T, U> const& pr) 
      { 
       os << "<" << std::get<0>(pr) << "," << std::get<1>(pr) << ">"; 
      } 
     }; 
    } 
} 

print_log_value 템플릿 당신이 pair<T,U> 같은 템플릿 값을 선언하지 않으면, 당신은 같은 것을 쓸 필요가 있도록 :

template<> 
struct print_log_value<MyType>{ /* implementation here*/ }; 

편집

부스트 1.59 이상을 사용하는 경우 대신 boost::test_tools::tt_detail 네임 스페이스를 사용해야합니다.

namespace boost 
{ 
    namespace test_tools 
    { 
     namespace tt_detail 
     { 
+0

Ah! 멋지다! 그게 훨씬 깔끔해. – nishantjr

9

operator itself in the std namespace 넣어보십시오 :

namespace std 
{ 
    ostream& operator<<(ostream& s, const pair<int,int>& p) { 
    s << '<' << p.first << ',' << p.second << '>'; 
    return s; 
    } 
} 

업데이트 : 아마도 이것이 왜 (적어도 LLVM에서) ADL fails :

Just like before, unqualified lookup didn't find any declarations with the name operator<< . Unlike before, the argument types both contain class types: one of them is an instance of the class template type std::basic_ostream , and the other is the type ns::Data that we declared above. Therefore, ADL will look in the namespaces std and ns for an operator<< . Since one of the argument types was still dependent during the template definition, ADL isn't done until the template is instantiated during Use, which means that the operator<< we want it to find has already been declared. Unfortunately, it was declared in the global namespace, not in either of the namespaces that ADL will look in!

+0

ADL이 BOOST_CHECK_EQUAL 내에 적용되지 않는 이유를 이해하지 못합니다. 부스트가 그 일을 막기 위해 무언가를합니까? – nishantjr

+0

@njr : 나는 얼마 전에 그것을 들여다 보았지만 근본 원인을 찾지 못했습니다. Afaik gcc는 ADL을 수행하고 llvm도 수행합니다. –

+1

이것은 나를 위해 작동하지만 정의되지 않은 동작 (http://en.cppreference.com/w/cpp/language/extending_std) 인 것 같습니다. 찾고, 정의되지 않은 동작을 피할 수있는 방법을 제공하는 다음과 같은 대답을 발견했다. http://stackoverflow.com/a/17573165/309334 – Eponymous

0

비슷한 것을 찾고 있었는데, 16 진수로 정수를 인쇄하기 위해 출력 문자열을 사용자 정의하는 방법. 연산자를 std 네임 스페이스에 삽입하면 작동하지만 내 테스트의 모든 BOOST_CHECK는 16 진수로 인쇄됩니다.

그래서 일부 글로벌 bool로 제어 할 수있는 부스트 네임 스페이스에 몇 가지 사용자 지정 연산자를 주입했습니다.

내 대답은 여기 boost-check-fails-to-compile-operator-for-custom-types을 참조하십시오.

관련 문제