Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调用非成员运算符重载_C++_Overloading_C++17_Name Collision - Fatal编程技术网

C++ 调用非成员运算符重载

C++ 调用非成员运算符重载,c++,overloading,c++17,name-collision,C++,Overloading,C++17,Name Collision,给定以下代码: #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 con

给定以下代码:

#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);
}
#包括
#包括
#包括
模板
constexpr bool ostreamable_,带=false;
模板//如果存在用户定义的重载
constexpr bool ostremable_与<

O、 T,std::void_T
使用std::operatorLine#1是
#include
@mnistic哈哈,在
jostream::operatorCan'T内有一条带有行号的注释,@Stargateur您需要激活
-std=c++17
,但clang不完全支持。在这里测试:@Peregring lk well c++17不是官方的,我使用c++1z和叮当声。另外,我的gcc不像你的那样编译。在你的问题中输入你使用的编译器版本是有用的,因为你使用了不稳定的特性。:o但是
std::operator@Peregring-lk我也在想这件事。显然,
运算符的虚拟重载(声明)是。。。(子)命名空间<代码> STD<代码>,不合格查找也会考虑并行代码(子)命名空间,如<代码>用户< /代码>,因为这也可以从<代码>::(即,从代码级别> JoSoos声明)访问。但我不能说。。。T.C.?@dfri我认为问题是,一旦你用一个非成员函数污染了查找空间,ADL(如果一个成员函数出现在正常的非限定查找中,它最初不会被考虑)就会被激活,并且通过参数发现用户定义的重载。我认为T.C.技巧是使用
std
名称空间激活ADL查找,因为在正常的“ADL模式”中,
std
名称空间已经被考虑,因为
jostream
继承自
std::reference\u wrapper
。因此,
using std::operator我想知道的是管理“ADL激活”的规则,并完全理解重载集是什么,使用和不使用该声明。
using std::operator<<;
operator<<(*this, v);