1

我正在使用库存有缺陷的operator<<,我想用我自己的版本替换它。它遵循ADL根据参数在库的名称空间中的成员资格来选择重载的习惯用法。有什么办法可以让C++选择我自己的operator<<覆盖ADL选择的超载

+0

@MichaelAaronSafyan如果ADL发现任何候选函数关联的名称空间,用户控制的名称空间或取决于作用域的名称空间不会影响超载集。重要的是当前'operator <<'在库的命名空间中,我不愿意在那里放置一些东西。 – 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); 

这是测试用表达式模板的工作。请注意,如果重写过载不匹配,从GCC 4.7的错误消息是一个红色的鲱鱼......它指的是在超负荷涉及std::流右值引用:

/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&)