【发布时间】:2021-05-03 13:26:33
【问题描述】:
以下内容不能在 clang 中编译,但在 GCC (godbolt) 中可以:
template <typename K, typename V>
std::ostream& operator<< (std::ostream& o, const std::map<K, V>& map)
{
const char* sep = "{";
for (const auto& x : map)
{
o << sep << "{" << x.first << ", " << x.second << "}";
sep = ", ";
}
return o << "}";
}
template <typename T>
std::ostream& operator<< (std::ostream& o, const std::vector<T>& vec)
{
const char* sep = "{";
for (const auto& x : vec)
{
o << sep << x;
sep = ", ";
}
return o << "}";
}
// Usage
int main()
{
std::map<int, std::vector<int>> t = {{1, {2, 3}}, {4, {5}}};
std::cout << t << std::endl;
return 0;
}
谁是对的?
顺便说一句,我知道它是 UB,但是将两个模板定义放在 namespace std 中也会使代码在 clang 上编译。
代码借自Is it possible to define operator<< for templated types?
【问题讨论】:
-
如果你只是交换
operator<<重载的顺序,它应该可以编译。 -
@TedLyngmo 是的,但是如果涉及到地图的矢量,那么更改顺序会破坏它^^
-
@Fareanor 当然 - 在这种情况下,必须转发声明。
template <typename T> std::ostream& operator<<(std::ostream& o, const std::vector<T>& vec); -
@TedLyngmo 同意,我说是因为在链接的问题中,OP 不想转发声明任何内容。
-
@Fareanor 啊,我明白了(我没有阅读借用代码的链接)。
标签: c++ language-lawyer