10

次のコードでは、コンパイラ エラーが発生します (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}' 左辺値を
'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]'<br>

テンプレート関数の宣言を取り除き、 と で置き換えると、T問題なくコンパイルされます (編集: 2 で置き換えては機能しますが、既定の引数として指定すること機能しません)。doubleN2TNN=2N

  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;
}

どうもありがとうございました。

4

2 に答える 2

13

あなたの宣言を考えてみましょう:

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しません。

于 2012-06-02T23:08:01.863 に答える
1

operator<<このように、あまり美的ではない方法で、指定されたテンプレートパラメーターを使用して呼び出すことができます。

operator<< <double,2>(std::cout, lower) << std::endl;
于 2012-06-02T22:56:38.457 に答える