繁体   English   中英

调用非成员运算符重载

[英]Calling non-member operator overloads

给出以下代码:

#include <iostream>
#include <functional>
#include <utility>

template<class O, class T, class = void>
constexpr bool ostreamable_with = false;

template<class O, class T> // If there's user-defined overloads
constexpr bool ostreamable_with<
    O, T, std::void_t<decltype(operator<<(std::declval<O>(),
                                          std::declval<T>()))>> = true;

struct jostream : std::reference_wrapper<std::ostream>
{
    using reference_wrapper::reference_wrapper;
    std::ostream& os() { return *this; }

    template<class T>
    jostream& operator<<(T const& v)
    {
        if constexpr(ostreamable_with<jostream&, T const&>)
            // This enables user-defined conversion on `v` too
            operator<<(*this, v); // #1
        else
            os() << v;

        return *this;
    }
};

namespace user {
    struct C
    { int a; };

    inline jostream& operator<<(jostream& os, C const& c)
    { return os << c.a; }
}

int main()
{
    jostream jos(std::cout);
    user::C u{1};
    jos << std::cref(u);
}

#1行中,有一个编译器错误,因为jostream有一个名为operator<<的函数成员,因此#1行中的调用( jostream::operator<<的注释行,而不是代码的第一行)正在尝试使用两个不存在的参数对jostream::operator<<进行显式调用。

是否有任何强制调用具有冲突名称的非成员函数的技巧? (除了调用进行实际调用的外部函数)。 A ::operator<< call显然不是解决方案,因为重载可能在用户命名空间内,如示例所示。

(使用gcc-7.2.0)

using std::operator<<;
operator<<(*this, v);

std*this的关联命名空间,所以这不会在重载集中引入任何新内容。 或者,定义一个命名空间范围operator<<获取一些虚拟类型并using它将其拉入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM