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:二进制'<lt;':找不到占用右手的运算符类型为"baz::Bar"的操作数(或者没有可接受的转换)
但是,如果我移除这两个名称空间中的任何一个(保留所有内容),或者移除Point
类的模板化<<
函数,一切都会正常工作。
这是MSVC中的一个错误吗?如何在不删除名称空间或函数的情况下进行编译
这是代码中的一个错误。功能的过载集分多个阶段构建:
- 从当前作用域向外查找匹配的函数名称。当在命名空间中找到名称时,将此命名空间中定义的所有重载添加到重载集并停止此进程
- 将参数相关查找(ADL)找到的所有重载添加到重载集
- 确定重载集是否包含唯一匹配和最佳重载。如果是,请使用否则会失败的选项
您的问题是,您的operator<<(std::ostream&, baz::Bar&)
是在全局命名空间中定义的,而不是在定义Bar
的命名空间中(在本例中为baz
)。在使用名称依赖于模板参数的模板中的运算符时,无论如何都需要将重载放入命名空间baz
中:在这种情况下,第一阶段将被省略,并且只检测通过参数依赖查找找到的名称。
顺便说一句,在修复输出运算符的位置时,您可能需要考虑将参数作为baz::Bar const&
传递,因为输出运算符通常不会修改格式化的实体。
相关文章:
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- 重载运算符 + 用于向量:命名空间标准
- 用于替换回调命名空间的模板?
- 是否有 GCC 警告,用于使用 C 库中的符号而不是通过命名空间 std?
- 用于更简洁代码的嵌套命名空间
- 为什么类型特征不适用于命名空间范围内的类型?
- 用于在函数内调用命名空间的任何缩写形式
- 匿名命名空间,用于在两个 cpp 文件中包含一个函数
- 内联类方法,用于调用其他文件的 anon 命名空间中的函数
- 用于在 C++ 中管理特定于平台的代码的内联命名空间技术
- CMakeLists.txt添加了表示命名空间的子文件夹(仅用于组织)
- 详细信息命名空间通常用于什么
- c++输出流不适用于模板和命名空间
- 用于"augments std"的代码的命名空间是什么?
- Cxx-prettyprint(用于标准容器)在命名空间std中定义了它的输出操作符——这违反了标准吗?
- 用于c++ 11的Vim语法高亮显示不会混淆其他高亮显示.例如,类/命名空间作用域
- 用于命名空间限定的c++预处理器令牌粘贴
- C++11 cmath 函数不在 std 命名空间中,适用于 android NDK w/gcc-4.8 或 clang