【问题标题】:override an overload selected by ADL覆盖 ADL 选择的重载
【发布时间】:2012-10-31 16:04:08
【问题描述】:

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

【问题讨论】:

  • @MichaelAaronSafyan 如果 ADL 在关联的命名空间中找到任何候选函数,则由用户控制或取决于范围的命名空间不会影响重载集。重要的是当前的operator<< 在库的命名空间中,我不愿意在里面放一些东西。

标签: c++ operator-overloading argument-dependent-lookup using-declaration


【解决方案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: 错误:初始化 'std::basic_ostream<_chart _traits>& std::operator&&, const _Tp&)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多