【问题标题】:My split function doesnt work, error C2664,我的拆分功能不起作用,错误 C2664,
【发布时间】:2020-11-04 20:33:09
【问题描述】:

所以这应该是拆分字符串并将其变成列表:

std::list<std::string> strSplit(std::string::iterator begin, std::string::iterator end, char c) {
    while(std::find(begin, end, c) != end) *std::find(begin, end, c) = '\0';
    return std::list<std::string>(begin, end);
}

但是编译器会抛出这个错误:

Error: C2664    
'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string
(const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)':
 cannot convert argument 1 from 'char' to 'std::initializer_list<_Elem>'

然后双击重定向到 xmemory0 行:881

...
template<class _Objty,
class... _Types>
static void construct(_Alloc&, _Objty * const _Ptr, _Types&&... _Args)
{   // construct _Objty(_Types...) at _Ptr
::new (const_cast<void *>(static_cast<const volatile void *>(_Ptr)))
    _Objty(_STD forward<_Types>(_Args)...);
}
...

【问题讨论】:

  • 您不能以这种方式从std::string 创建std::list。您需要遍历字符串,找到您感兴趣的子字符串并将它们推送到列表中。
  • std::list 构造函数#5 (en.cppreference.com/w/cpp/container/list/list) 采用迭代器范围开始和结束,所以这不是问题。问题是 std::string::iterator 遍历字符串中的字符,因此 strSplit 函数需要返回 std::list 但这并不能解决您的问题,因为您希望粘贴 '\0' into a string 将其变为 2 个字符串 - 它不会,您最终会得到一个包含 '\0' 字符的字符串。您实际上需要创建两个单独的 std::string 对象并将它们推送到列表中。
  • 你需要像onlinegdb.com/H15RI5gtw这样的东西
  • @JerryJeremiah 为什么不用所有文本和代码添加答案?我可以看到与现有答案的一个主要区别是,如果begin == end,它将创建一个带有空字符串的std::list&lt;std::string&gt; - 但也许这正是OP想要的。
  • 当我开始编写代码时,没有答案。当我完成时,有两个。我的答案基本相同,所以我认为做出与现有答案相同的答案没有多大意义,但我不想浪费代码,所以我想我会分享它。

标签: c++ c++11 c2664


【解决方案1】:

您的函数存在多个问题。除了不编译。它试图改变它试图复制到列表中的字符串,这是没有意义的。它还无缘无故地多次使用std::find,而不是存储其结果并重用它。这是我的版本:

std::list<std::string> strSplit(std::string::const_iterator const begin,
                                std::string::const_iterator const end,
                                char const c) {
  std::list<std::string> res;
  if (end != begin) {
    auto it = begin, prev = begin;
    while ((it = std::find(it, end, c)) != end) {
      res.emplace_back(prev, it);
      prev = ++it;
    }
    res.emplace_back(prev, end);
  }

  return res;
}

【讨论】:

    【解决方案2】:

    您需要使用从std::find 获得的返回迭代器,并从中实际创建一个std::string(以及begin 迭代器)。将c 替换为\0 只会使原始字符串中包含\0,因此生成的std::list&lt;std::string&gt; 中的唯一字符串也会看起来像。

    关于该主题 - 您可能应该为此使用 std::string::const_iterator,因为您可能不应该更改原始字符串。

    例子:

    #include <iterator>
    
    std::list<std::string> strSplit(std::string::const_iterator begin,
                                    std::string::const_iterator end, char c) {
        std::list<std::string> retval;
        if(begin == end) return retval; // nothing to do here
    
        while(true) {
            auto fit = std::find(begin, end, c);
            retval.emplace_back(begin, fit); // creates a string in-place using begin and fit
            if(fit == end) return retval;    // if end was found, return what we got        
            begin = std::next(fit);          // else, go another round
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-05
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      相关资源
      最近更新 更多