3

誰かが vector.insert() メソッドの 2 番目の引数について説明してくれるかどうか疑問に思っています。

iterator insert (iterator position, const value_type& val);

たとえば、wstring 型のベクトルがあり、特定の位置に wstring を挿入したいと考えています。イテレータを使用して位置を設定する方法を理解しました:

wstring word = "test";
int insertion_pos = 3;
iterator it = words.begin();
words.insert( it + insertion_pos, word );

しかし、その 2 番目の引数についてはどうでしょうか。wstring オブジェクトを insert() メソッドに渡すにはどうすればよいですか? どうもありがとう。

乾杯、

マーティン

完全な例:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <wchar.h>
#include <vector>

using namespace std;

int main(void) {
    // Initialize the vecor with three words.
    vector<wstring> words;
    wstring word1 = "FirstWord"; // Error msg: no viable conversion from 'const char     [10]' to 'wstring' (aka 
                             //            'basic_string<wchar_t>')
    wstring word2 = "SecondWord"; // same here
    wstring word3 = "ThirdWord"; // same here

    words.push_back(word1);
    words.push_back(word2);
    words.push_back(word3);

    // Now try to insert a new word at position 2 (i.e. between "SecondWord "and "ThirdWord"
    int position = 2;
    wstring word4 = "InsertThis"; // same error as above
    iterator it = words.begin(); // Error: use of class template iterator requires template 
                             //      arguments
    words.insert( it + position, word4 ); 
//  Invalid arguments ' Candidates are:     __gnu_cxx::__normal_iterator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> 
//   *,std::vector<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,std::allocator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>>> 
//   insert(__gnu_cxx::__normal_iterator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> 
//   *,std::vector<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,std::allocator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>>>, 
//   const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> &) void 
//   insert(__gnu_cxx::__normal_iterator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> 
//   *,std::vector<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,std::allocator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>>>,     
//   unsigned long int, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> &) void 
//   insert(__gnu_cxx::__normal_iterator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> 
//   *,std::vector<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,std::allocator<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>>>>, 
//   #10000, #10000) '

    return EXIT_SUCCESS;
}
4

1 に答える 1

5

問題の明確な例をありがとう。これは、変更に関するいくつかのコメントを含む修正版です。Mac OS Xでclangを使用してコンパイルします。

変更の 1 つは、文字列リテラルの前の "L" です。これは、後に続く文字列リテラルが wchar_t 型であることを示しますこれも参照してください。

ワイド文字/Unicode/utf のサポートは、解決しようとしている問題で必要な場合にのみ追加します。

// #include <stdio.h>   prefer "cstdio" to stdio.h; not used in example                                                                                                                                 
// #include <stdlib.h>  same                                                                                                                                                                            
#include <iostream>
#include <string>
// #include <wchar.h>  not used in example                                                                                                                                                              
#include <vector>

using namespace std;

// simplify to main()
int main() {
  // Initialize the vecor with three words.                                                                                                                                                             
  vector<wstring> words;
  wstring word1(L"FirstWord"); // Use Constructor, no assignment operator=                                                                                                                              
  wstring word2(L"SecondWord");
  wstring word3(L"ThirdWord");

  words.push_back(word1);
  words.push_back(word2);
  words.push_back(word3);

  int position = 2;
  wstring word4(L"InsertThis");
  // iterator depends on type of container                                                                                                    
  vector<wstring>::iterator it = words.begin();                                                                                                                                                         
  words.insert( it + position, word4 );

  for (const std::wstring& w : words)
    std::wcout << w << " ";
  std::wcout << std::endl;

  return EXIT_SUCCESS;
}

挿入呼び出しを理解する

ベクトルのinsertメンバー関数のプロトタイプは次のとおりです。

  iterator insert( iterator pos, const T& value );

whereTは、テンプレート パラメータとして指定する型です。つまりstd::wstring、この場合です。

イテレータはoperator+、次のセマンティクスでオーバーロードされています: iterator it + integer 2iterator を「インクリメント」した位置 2 の新しいイテレータを返しますit

  words.insert( it + position, word4 );

提案

挿入位置の決め方に注意が必要です。

イテレータ+オフセットを使用するよりも、イテレータを使用してベクトルを「歩く」方が良い方法(より保守しやすい)だと思います。イテレータに慣れていない場合は、イテレータの使用方法を学ぶチャンスです。

これにより、この回答の以前のバージョンで説明した潜在的な状況が回避されます。これは、ベクトルの末尾を超えて反復子を誤ってオフセットし、セグメンテーション違反につながる可能性があります。

于 2013-11-02T22:30:04.790 に答える