我正在使用Boost variant在Microsoft Windows 7和Visual Studio 2010上编译x64服务:

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 << ' ';
        });
    }
}

我试图删除右手的限定词和引用,认为按值传递副本会破坏限定词(就共享指针而言可能不太出色),并且我尝试将声明从 namespace 移至全局范围,希望ADL出于某种原因会选择它(从概念上讲我得到了ADL,但对我来说仍然只有一点点黑魔法)。

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

最佳答案

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

关于c++ - ADL找不到具有针对用户定义类型的适当限定符的流运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10590898/

10-11 22:47
查看更多