ADL 无法找到具有用户定义类型的适当限定符的流运算符

ADL can't locate stream operator with appropriate qualifiers for a user defined type

本文关键字:运算符 类型 定义 用户 ADL      更新时间:2023-10-16

我正在使用Visual Studio 2010在Windows 7 Microsoft编译x64服务,使用Boost变体如下:

namespace my_ns
{
    typedef struct {} empty_t;
    typedef std::pair<size_t, std::shared_ptr<char>> string_t;
    typedef boost::variant<empty_t, double, long, string_t> variant_t;
    typedef std::map<unsigned short, variant_t> variant_map_t;
}

当我摆脱string_t并用 std::string 取而代之的那一天,就是我买老板和团队甜甜圈的那一天。但这不是我们在这里的原因...

Boost 变体支持其包含类型的流运算符,前提是该类型具有重载。所以我有:

namespace my_ns
{
    std::ostream &operator<<(std::ostream &, const empty_t &);
    std::ostream &operator<<(std::ostream &, const string_t &);
}

然而,我被错误消息所困扰:

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const T3' (or there is no acceptable conversion)

T3 指string_t。

生成错误的有问题代码存在于以下上下文中。它很冗长,因此您(读者(具有相关的上下文信息:

namespace my_ns
{
    void Widget::public_method(std::ostringstream &os) const
    {
        //variant_map_t Widget::the_map; // Private Widget member.
        // This here is a C++11 lambda in a standard loop algorithm, if you didn't recognize the syntax.
        std::for_each(the_map.begin(), the_map.end() [&os](variant_map_t::value_type value)
        {
            os << value.first << '=' << value.second << ' ';
        });
    }
}

我尝试删除右手限定符和引用,认为按值传递副本会取消限定符(鉴于共享指针可能不是那么出色(,并且我尝试将声明从命名空间移动到全局范围,希望 ADL 会出于某种原因选择它(我得到 ADL,从概念上讲, 但对我来说,它仍然只有一点点黑魔法(。

我不知道还能做什么。除了编译器无法找到具有 const 限定 rhs 的插入运算符之外,此错误的性质是什么?当它就在那里时,这怎么可能?分辨率是多少?

typedef 添加到命名空间没有帮助,std::pairstd::ostream仍然是 std 命名空间的一部分。因此,编译器将在那里查找<<运算符,而不是在您的命名空间中查找。