1. ホーム
  2. c++

[解決済み] テンプレート宣言はブロックスコープに表示できない

2022-02-04 08:30:10

質問

リップマンを勉強しているのですが、勉強しかしていません。ここでは、ベクターの最小限の要素を返すコードを書こうとしています。Codeblocksでコンパイルすると、"A template declaration cannot appear at block scope"と表示されます。以下はそのコードです。

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
    template <class elemType>
    elemType save;
    elemType min (const std::vector<elemType> &vec) {
      std::vector<elemType>::iterator it = vec.begin(), end_it = vec.end();
      std::vector<elemType>::iterator iter = std::next(it, 1);
      for ( ; it != end_it; it++ ) {
        if ( *it < *(it + 1) ) {
          save = *it;
        }
        if (save < *it) {
          save = *it;
        }
      }
    };

    int massiv[10] = {35, 66, 98, 15, 32, 41, 24, 90, 55, 100};
    std::vector<int> vec_train(massiv,massiv+10);


    min(vec_train);
    return 0;
}

解決方法は?

関数内部でテンプレートを定義することはできませんし main は関数です。そのため min 関数テンプレートはmainの外側で、mainの前にあります。

あなたのコードには、他にもいくつかの問題があります。その

template <class elemType>

は、関数定義の直前に記述する必要があります。置くこと

elemType save;

を挟むのは正しい構文ではありません。

もう一つの問題は、ベクトル中の最小値を選択するアルゴリズムです。なぜこのような

if (*save < *(it + 1) ) { save = *it; }

そして、この

if (*save < *it ) { save = *it; }

を同時に使用するのですか?

ここに、おそらくあなたが望むものがあるはずです。

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

template <class elemType>
const elemType& min(const std::vector<elemType>& vec) {
  typename std::vector<elemType>::const_iterator
    select = vec.begin(),
    it = std::next(select),
    end = vec.end();
  for ( ; it != end; ++it ) {
    if ( *it < *select ) select = it;
  }
  return *select;
};

int main() {
  int massiv[10] = {35, 66, 98, 15, 32, 41, 24, 90, 55, 100};
  std::vector<int> vec_train(massiv,massiv+10);

  std::cout << min(vec_train) << std::endl;
  return 0;
}

空のベクトルを処理する必要がある場合は、以下のように

if (!vec.size()) throw std::length_error("empty vector passed to min");

のように、関数の最初に置くか、要素参照ではなくイテレータを返します。 end() は空のベクトルでもきちんと定義されています。