1

결함이있는 라이브러리를 사용하고 있습니다. operator<<을 내 버전으로 바꾸고 싶습니다. ADL이 라이브러리의 네임 스페이스에서 인수의 멤버십을 기반으로 오버로드를 선택하는 관용구를 따릅니다. C++에서 내 operator<<을 대신 선택하는 방법이 있습니까?은 ADL에 의해 선택된 과부하를 무시합니다.

+0

@MichaelAaronSafyan : 재정의 과부하가 일치하지 않는 경우, GCC 4.7에서 오류 메시지가 ... 빨간 청어는 스트림를 rvalue 참조를 포함 std::에 과부하를 의미합니다 관련 네임 스페이스, 사용자가 제어하는 ​​네임 스페이스 또는 범위에 따라 오버로드 집합에 영향을주지 않습니다. 중요한 것은 현재의 연산자 <<가 라이브러리의 네임 스페이스에 있고, 거기에 뭔가를 넣지 않으려한다는 것입니다. – Potatoswatter

답변

1

하나의 차선책은 라이브러리 유형을 중심으로 래퍼 클래스를 선언하는 것입니다.

일반적인 구현은 다음과 같습니다이 표현 템플릿 작업을 테스트

/* Namespace-specific reference wrapper type. 
    Associates a function argument with the desired namespace. 
    Declare a new use_local_t for each namespace with an overriding overload */ 
template< typename t > 
struct use_local_t 
    { t ref; }; 

template< typename t > 
use_local_t< t && > 
use_local(t &&o) 
    { return { std::forward<t>(o) }; } 

/* The overriding overload. 
    Instead of overloading on a specialization of use_local_t, use the 
    general template and enable_if. This allows for the various kinds of 
    references that use_local_t might forward, and conversion of the function 
    argument to the expected library_type parameter. */ 
template< typename t > 
inline 
typename std::enable_if< 
    std::is_convertible< t, library_type const & >::value, 
    std::ostream & 
>::type 
operator<< (std::ostream &s, use_local_t<t> ul) { 
    return s << ul.ref.foo; 
} 

std::cout << my_namespace::use_local(library_obj); 

. ADL은 어떤 후보 함수를 발견하면

/opt/local/include/gcc47/c++/ostream:600:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&)