Question

I am wondering, if anyone could explain to me the second argument in the vector.insert() method:

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

For example, I have a vector of type wstring and I would like to insert a wstring at a given position. I have figured out how to set the position using an iterator:

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

But what about that second argument? How can I pass a wstring object to the insert() method? Thanks a lot.

Cheers,

Martin

Full example:

#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;
}
Was it helpful?

Solution

Thanks for the clear example of the issue. Here is a modified version with some comments about changes. It compiles for me using clang on Mac OS X.

One change is the "L" in front of the string literal. This is an indicator that the string literal to follow is of type wchar_t. See also this.

Wide character/unicode/utf support is something I would add only if it's needed in the problem you're trying to solve.

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

Understanding the insert call

The prototype for the vector's insert member function is:

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

where T is the type you give as a template parameter, i.e. std::wstring in this case.

Iterators have operator+ overloaded, with the following semantics: iterator it + integer 2 returns a new iterator with a position 2 "increments" past the iterator it.

  words.insert( it + position, word4 );

Suggestion

One thing to be careful about it how you determine an inerstion position.

I think it would be better practice (more maintainable) to use an iterator to "walk along" the vector, rather than using iterator+offset. If you're not very comfortable with iterators, this would be a chance to learn how to use them.

This would avoid a potential situation, discussed in a previous version of this answer, where you accidentally offset your iterator past the end of the vector, leading to a segmentation violation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top