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:
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'baz::Bar' (or there is no acceptable conversion)
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.
Is this a bug in 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
). 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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.