Clang中的二义性运算符<<重载

amo*_*osk 6 c++ language-lawyer

以下代码不能在 clang 3.5+ 中编译,但可以在所有 gcc 版本和 clang < 3.5 中编译。

struct Logger {
    template <class T>
    Logger& operator<<(const T& /*val*/)
    {
        // m_buf << val;
        return *this;
    }
};

struct Value {
    template <class Stream>
    friend Stream& operator<<(Stream& os, const Value& /*val*/)
    {
        // os << m_val;
        return os;
    }
};

int main()
{
    Logger logger;
    Value value;
    logger << value;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

叮当错误是

<source>:23:12: error: use of overloaded operator '<<' is ambiguous (with operand types 'Logger' and 'Value')

    logger << value;

    ~~~~~~ ^  ~~~~~

<source>:3:13: note: candidate function [with T = Value]

    Logger& operator<<(const T& /*val*/)

            ^

<source>:12:20: note: candidate function [with Stream = Logger]

    friend Stream& operator<<(Stream& os, const Value& /*val*/)

                   ^
Run Code Online (Sandbox Code Playgroud)

根据标准,clang 还是 gcc,谁是正确的?如果叮当声,我如何正确编写带有“<<”的记录器,将支持“<<”的任何值重定向到另一个流?