【问题标题】:C++ how to insert wstring into vector at given positionC ++如何将wstring插入到给定位置的向量中
【发布时间】:2013-11-02 22:21:58
【问题描述】:

我想知道,是否有人可以向我解释 vector.insert() 方法中的第二个参数:

迭代器插入(迭代器位置,const value_type& val);

例如,我有一个 wstring 类型的向量,我想在给定位置插入一个 wstring。我已经弄清楚如何使用迭代器设置位置:

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

但是第二个参数呢?如何将 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;
}

【问题讨论】:

    标签: c++ vector wstring


    【解决方案1】:

    感谢您提供清晰的问题示例。这是一个修改后的版本,其中包含一些关于更改的 cmets。它在 Mac OS X 上使用 clang 为我编译。

    一个变化是字符串文字前面的“L”。这是一个indicator,后面的字符串文字是 wchar_t 类型。另见this

    宽字符/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;
    }
    

    了解插入调用

    vector 的insert member function 的原型是:

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

    其中T 是您作为模板参数提供的类型,在本例中为std::wstring

    迭代器重载了 operator+,具有以下语义:iterator it + integer 2 返回一个新迭代器,其位置比迭代器 it 高 2 个“增量”。

      words.insert( it + position, word4 );
    

    建议

    要注意如何确定插入位置。

    我认为使用迭代器“沿着”向量“行走”而不是使用迭代器+偏移会更好(更易于维护)。如果您对迭代器不太熟悉,这将是一个学习如何使用它们的机会。

    这将避免在此答案的先前版本中讨论过的潜在情况,即您不小心将迭代器偏移超过向量的末尾,从而导致分段违规。

    【讨论】:

    • 非常感谢 Nicholas 的详细回答。当然,你是对的:我应该更准确地说明问题出在哪里。问题是带有 insert() 语句的行甚至不为我编译。我在 Eclipse 中收到“无效参数”错误。万一它有所作为,我在 Mac OS X 10.8.4 上使用 Eclipse Kepler 并且项目正在使用 Mac OS GCC 工具链。
    • 能否请您发布导致此问题的minimal, compilable example?或者至少,如果问题得到解决,您希望编译一个示例?我不熟悉 wstring,但听起来您对 words (及其值类型)的定义可能与您尝试插入的 word 定义不兼容(混合字符串和 wstring?)。最后,如果您可以打印编译器消息的相关行,那将有所帮助。
    • 好吧,下面的代码不能编译,如果要编译,我不会有任何问题。但它应该有助于说明问题 -> 请参阅上面编辑过的问题。
    • 我似乎找到了解决 wstring 初始化问题的方法:下面的帖子描述了一种显式转换方法。 stackoverflow.com/questions/10737644/…。来自 Java 世界,对我来说似乎有点疯狂,一个人必须通过这个来初始化字符串,但无论如何。
    • 这里没有参数。 :-) 如果它解决了您的编译问题,您可以将其标记为“已回答”,那将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2021-12-23
    • 2014-05-23
    相关资源
    最近更新 更多