繁体   English   中英

c ++输出流不使用模板和命名空间

[英]c++ Output stream not working with templates and namespaces

我有以下代码:

#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;
}

}

它不在MSVC上编译并失败,并显示以下错误消息:

错误C2679:二进制'<<':找不到哪个运算符采用'baz :: Bar'类型的右手操作数(或者没有可接受的转换)

但是,如果我删除任何两个名称空间(保留所有内容)或删除Point类的模板化<<函数,一切正常。

这是MSVC中的错误吗? 如何在不删除命名空间或函数的情况下进行编译?

这是您的代码中的错误。 函数的重载集是在多个阶段构建的:

  1. 从当前范围向外找到匹配的函数名称。 在命名空间中找到名称时,将此命名空间中定义的所有重载添加到重载集并停止此过程。
  2. 将依赖于参数的查找(ADL)找到的所有重载添加到重载集。
  3. 确定过载集是否包含唯一匹配和最佳过载。 如果是这样,请使用否则失败。

您的问题是您的operator<<(std::ostream&, baz::Bar&)是在全局命名空间中定义的,而不是在定义了Bar的命名空间中定义的(在本例中为baz )。 无论如何,当从具有名称取决于模板参数的模板使用运算符时,需要将重载置于名称空间baz中:在这种情况下,第一阶段被省略,并且仅检测由参数依赖查找找到的名称。

顺便说一句,在修复输出操作符的位置时,您可能需要考虑将参数作为baz::Bar const&传递,因为输出操作符通常不会修改格式化的实体。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM