提问人:Liu Weibo 提问时间:11/7/2023 最后编辑:Liu Weibo 更新时间:11/7/2023 访问量:63
为什么 G++ 和 Clang++ 之间的模板初始化行为不同?
why there's a different behavior in template initialization between g++ and clang++?
问:
#include <iostream>
#include <vector>
#include <array>
template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &vec)
{
if (vec.empty()) {
out << "[]";
return out;
}
out << '[';
for (int i = 0; i < vec.size() - 1; i++) {
out << vec[i] << ", ";
}
return out << vec.back() << ']';
}
template <class T, std::size_t C> std::ostream &operator<<(std::ostream &out, const std::array<T, C> &arr)
{
if (arr.empty()) {
out << "<>";
return out;
}
out << '<';
for (int i = 0; i < arr.size() - 1; i++) {
out << arr[i] << ", ";
}
return out << arr.back() << '>';
}
#include <string>
#define dbg(...) logger(__LINE__, #__VA_ARGS__, __VA_ARGS__)
template <typename... Args> void logger(int line, std::string vars, Args &&...values)
{
std::cerr << "Ln " << line << ": " << vars << " = ";
std::string delim = "";
(..., (std::cerr << delim << values, delim = ", "));
std::cerr << std::endl, std::cerr.flush();
}
using namespace std;
int main()
{
using a2i = array<int, 2>;
using va2i = vector<a2i>;
using a4v = array<va2i, 4>;
a4v a4;
a4[0].push_back({3, 5});
a4[1].push_back({9, 8}), a4[1].push_back({1, 2});
dbg(a4);
return 0;
}
编译上面的代码,你会得到不同的结果。https://rextester.com/l/cpp_online_compiler_clang
https://rextester.com/l/cpp_online_compiler_gcc
g++ one 将按预期编译和工作,而 clang++ 抱怨如下:
96501129/source.cpp:36:6: warning: pack fold expression is a C++17 extension [-Wc++17-extensions]
(..., (std::cerr << delim << values, delim = ", "));
^
96501129/source.cpp:13:13: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup
out << vec[i] << ", ";
^
96501129/source.cpp:25:13: note: in instantiation of function template specialization 'operator<<<std::__1::array<int, 2> >' requested here
out << arr[i] << ", ";
^
96501129/source.cpp:36:31: note: in instantiation of function template specialization 'operator<<<std::__1::vector<std::__1::array<int, 2>, std::__1::allocator<std::__1::array<int, 2> > >, 4>' requested here
(..., (std::cerr << delim << values, delim = ", "));
^
96501129/source.cpp:52:5: note: in instantiation of function template specialization 'logger<std::__1::array<std::__1::vector<std::__1::array<int, 2>, std::__1::allocator<std::__1::array<int, 2> > >, 4> &>' requested here
dbg(a4);
^
96501129/source.cpp:31:18: note: expanded from macro 'dbg'
#define dbg(...) logger(__LINE__, #__VA_ARGS__, __VA_ARGS__)
^
96501129/source.cpp:17:49: note: 'operator<<' should be declared prior to the call site
template <class T, std::size_t C> std::ostream &operator<<(std::ostream &out, const std::array<T, C> &arr)
^
96501129/source.cpp:15:16: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup
return out << vec.back() << ']';
^
96501129/source.cpp:17:49: note: 'operator<<' should be declared prior to the call site
template <class T, std::size_t C> std::ostream &operator<<(std::ostream &out, const std::array<T, C> &arr)
^
1 warning and 2 errors generated.
似乎 clang 无法在最内层中以 as 实例类型初始化对象上的运算符模板。<<
ostream
array<int, 2>
array
大小为 4 的最外数组和数组的向量被成功呈现,而最里面的数组则没有在这种类型的 上渲染。array<vector<array<int, 2>>, 4>
我想知道这个抱怨的原因是什么,以及如何修复代码以使其在 gcc 和 clang 上工作
答: 暂无答案
评论
namespace std
<<
template <typename T> struct PrintToStream{...};