【发布时间】:2021-07-25 19:59:16
【问题描述】:
我想打印std::maps等STL类型的值,例如:
int main()
{
std::map<int, std::vector<int>> t = {{1, {2, 3}}, {4, {5}}};
std::cout << t << std::endl;
return 0;
}
这会失败,因为没有为这些类型定义 operator<<。
如果我尝试自己定义它,我还必须转发声明我的定义,否则编译失败:
error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup
o << sep << "{" << x.first << ", " << x.second << "}";
...
note: 'operator<<' should be declared prior to the call site std::ostream& operator<< (std::ostream& o, const std::vector<T>& vec)
这很不幸,因为必须前向声明方法需要为每种类型使用两个包含(先前向声明,然后是实现)。
- 有没有办法以模块化的方式为模板类型定义
operator<<? - 这就是为什么
operator<<不能用于开箱即用的 STL 类型的原因吗?
【问题讨论】:
-
请在问题中包含minimal reproducible example
-
@largest_prime_is_463035818 不就是我在最后一行中链接到的参考吗?
-
如果您发布有错误的代码,这会更简单。当我必须修改重现错误的代码时,我可能会以不同于产生错误的代码的方式对其进行更改。尽管当我删除前向声明时代码实际上也可以正常编译:godbolt.org/z/GxThvGd1M.
-
不允许将定义放入命名空间
std(极少数例外)。一种解决方法是像您一样进行前向声明,或者使用自定义类型,如struct MyInt{ int x; };而不是int。这些自定义类型具有关联的命名空间,并且所有模板参数的命名空间都与 ADL 相关 -
@largest_prime_is_463035818:原因之一是 ODR(定义
operator <<(std::ostream&, std::map<K, V>)的几个库)。