1

これは、ベクトルの最後の 4 つの要素で文字列「gold」を検索しようとする私のコードです。文字列は正常に検出されますが、安全に実行できますか? MS VS2008 で動作します。

#include <vector>
#include <iostream>


int main() {

   char random[] = {'a','b','c','d','e','f','g'};
   char tofind2[] = {'g','o','l','d'};
   std::vector<char> buf;
   buf.insert(buf.end(), random, random+sizeof(random));
   buf.insert(buf.end(), tofind2, tofind2+sizeof(tofind2));
   if(buf.size() >= sizeof(tofind2) && std::equal(buf.end()-sizeof(tofind2), buf.end(), tofind2)) {
      std::cout << "found value in last " << sizeof(tofind2) << " elements of array\n";
   }
}
4

2 に答える 2

3

これは、少なくとも 4 つの要素が含まれている限り安全ですvector。通常、反復子はその範囲の境界を越えて移動でき、ランダム アクセス反復子は整数型の加算/減算によって移動できます。 std::vectorの反復子はランダム アクセス反復子です。

要素が 4 つ未満の場合、これは安全ではなく、未定義の動作につながります (イテレータを逆参照する前であっても!)

注意したい場合は、そのケースを確認する必要があります。

template<typename Container>
auto nth_last_iterator( Container&& c, int n )
  -> declval( std::begin(c) )
{
  if (n > std::end(c) - std::begin(c))
    n = std::end(c) - std::begin(c);
  return std::end(c)-n;
}

これは C++11 であり、任意のランダム アクセス コンテナーで動作します。次に、次のようになります。

if(std::equal(nth_last_iterator(buf,sizeof(tofind2)), buf.end(), tofind2)) {
  std::cout << "found value in last " << sizeof(tofind2) << " elements of array\n";
}

@DavidHammen が指摘したように、次のsizeof(tofind2)場合にのみ機能しますsizeof(tofind2[0]) == 1template次のように、配列のサイズを検出し、その弱点を持たない、比較的簡単に作成できる s がいくつかあります。

template<typename T, std::size_t N>
std::size_t lengthof( T(&)[N] ) {
  return N;
}

これは有効な C++03 であり、C++11 ではそれを作成できますconstexpr。(そして、それを拡張することもできstd::array< T, N > const&ます)

于 2013-06-26T17:23:43.557 に答える
0

これは正しいです。イテレータ演算が許可されているため、安全に実行できます ( http://www.cplusplus.com/reference/iterator/RandomAccessIterator/ )。

于 2013-06-26T17:24:06.273 に答える