我正在使用 Visual Studio 2010 在 Microsoft Windows 7 上编译 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 的插入运算符之外,这个 bug 的本质是什么?怎么可能,当它就在那里的时候?决议是什么?