[英]c++ Output stream not working with templates and namespaces
I have the following code: 我有以下代码:
#include <fstream>
// Removing this namespace (keeping the content) makes it work
namespace baz {
class Bar {
};
}
std::ostream & operator<<(std::ostream & stream, baz::Bar & value) {
return stream;
}
// Removing this namespace (keeping the content) makes it work
namespace goo {
template <class Type>
struct Point {
};
// Removing this function makes it work
template <class Type>
std::ostream& operator<< (std::ostream& stream, const Point<Type> &point);
void foo() {
baz::Bar test;
std::ofstream stream;
stream << test;
}
}
It does not compile on MSVC and fails with the following error message: 它不在MSVC上编译并失败,并显示以下错误消息:
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'baz::Bar' (or there is no acceptable conversion)
错误C2679:二进制'<<':找不到哪个运算符采用'baz :: Bar'类型的右手操作数(或者没有可接受的转换)
However, if I remove any of the two namespaces (keeping all the contents) or remove the templated <<
function for the Point
class, everything works fine. 但是,如果我删除任何两个名称空间(保留所有内容)或删除
Point
类的模板化<<
函数,一切正常。
Is this a bug in MSVC? 这是MSVC中的错误吗? How can I make it compile without removing the namespaces or the function?
如何在不删除命名空间或函数的情况下进行编译?
This is a bug in your code. 这是您的代码中的错误。 The overload set for functions is build in multiple stages:
函数的重载集是在多个阶段构建的:
Your problem is that your operator<<(std::ostream&, baz::Bar&)
is defined in the global namespace rather than in the namespace where Bar
is defined (in this case baz
). 您的问题是您的
operator<<(std::ostream&, baz::Bar&)
是在全局命名空间中定义的,而不是在定义了Bar
的命名空间中定义的(在本例中为baz
)。 Putting the overload into namespace baz
is needed anyway when using the operator from a template with a name depending on a template argument: in that case the first stage is omitted and only names found by argument dependent look-up are detected. 无论如何,当从具有名称取决于模板参数的模板使用运算符时,需要将重载置于名称空间
baz
中:在这种情况下,第一阶段被省略,并且仅检测由参数依赖查找找到的名称。
BTW, while fixing the location of the output operator you might want to consider passing the argument as baz::Bar const&
as output operators normally don't modify the formatted entity. 顺便说一句,在修复输出操作符的位置时,您可能需要考虑将参数作为
baz::Bar const&
传递,因为输出操作符通常不会修改格式化的实体。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.