Я использую библиотеку с дефектом operator<<
, который я хочу заменить своей собственной версией. Это следует из идиомы, где ADL выбирает перегрузку на основе членства аргумента в пространстве имен библиотеки. Есть ли способ заставить C ++ выбрать свой operator<<
вместо?
Одно неоптимальное решение — объявить класс-оболочку вокруг типа библиотеки.
Общая реализация будет выглядеть так:
/* 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 );
Это проверено для работы с шаблонами выражений. Обратите внимание, что если перегрузка переопределения не совпадает, сообщение об ошибке из GCC 4.7 представляет собой красную сельдь … оно относится к перегрузке в std::
с использованием ссылки на rvalue потока:
/ opt / local / include / gcc47 / c ++ / ostream: 600: 5: ошибка: инициализация аргумента 1 ‘std :: basic_ostream<_CharT, _Traits>& станд :: оператор<<(Станд :: basic_ostream<_CharT, _Traits>&&, const _Tp&)
Других решений пока нет …