为什么 gcc 无法推断数组参数的模板化大小?(C++11)

Why can't gcc deduce templated size for array argument? (C++11)

本文关键字:C++11 gcc 参数 数组 为什么      更新时间:2023-10-16

以下代码给出了一个编译器错误(gcc-4.7 使用 -std=c++11 运行):

#include <iostream>
#include <array>
template <typename T, int N>
std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) {
  int i;
  for (i=0; i<N-1; ++i)
    os << arr[i] << " ";
  os << arr[i];
  return os;
}
int main() {
  std::array<double, 2> lower{1.0, 1.0};
  std::cout << lower << std::endl;
  return 0;
}

错误信息:

tmp6.cpp:在函数 'int main()' 中: tmp6.cpp:16:16: 错误: 无法绑定
'std::ostream {aka std::basic_ostream}' lvalue to
"std::basic_ostream&&" 在包含自
/usr/include/c++/4.7/iostream:40:0,
来自 tmp6.cpp:1:/usr/include/c++/4.7/ostream:600:5: 错误: 初始化 'std::basic_ostream<_CharT 的参数 1,
_Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits; _Tp = std::array]'

当我摆脱模板函数声明并将T替换为 double 并用 2 替换N时,它的编译效果很好(编辑:保留 T 并将 N 替换为 2 个作品,但指定 N=2 作为 N 的默认参数不起作用。

  1. 有谁知道为什么 gcc 不能自动绑定它?
  2. 使用显式指定的模板参数调用 << 运算符的语法是什么?

回答问题2:operator<<<double, 2>(std::cout, lower);

编辑:对于以下函数也是如此,该函数仅在数组大小中模板化:

template <int N>
void print(const std::array<double, N> & arr) {
  std::cout << "print array here" << std::endl;
}
int main() {
  std::array<double, 2> lower{1.0, 1.0};
  print<2>(lower); // this works
  print(lower);    // this does NOT work
  return 0;
}

非常感谢您的帮助。

考虑你的声明:

template <typename T, int N>
std::ostream & operator <<(std::ostream & os, const std::array<T, N> & arr) {

std::array的定义是:

template<typename T, std::size_t N> class array {...};

您使用的是int而不是std::size_t,这就是它不匹配的原因。

您可以使用指定的模板参数以这种不太美观的方式调用operator<<

operator<< <double,2>(std::cout, lower) << std::endl;