使用 boost::algorithm:string:split 和 std::string 的 g++ 无效初始化错误

Posted

技术标签:

【中文标题】使用 boost::algorithm:string:split 和 std::string 的 g++ 无效初始化错误【英文标题】:g++ invalid initialization error using boost::algorithm:string:split and std::string 【发布时间】:2016-03-15 21:07:44 【问题描述】:

我正在将一些 C++ 代码从 Windows 移植到 Linux(最终是 OSX)。由于 Windows 不合规性,会出现大量 C++ 问题。我似乎已经克服了这一点,但现在面临着一个提升问题。

基本上,我想切掉一个字符串,其中感兴趣的子字符串用逗号分隔,然后将它们推入一个字符串向量。这会导致 g++ 中的错误,但它可以在 Visual Studio 中正常编译

这个程序准确地说明了这个问题:

#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>

int main (void) 


  std::vector<std::string> str_vec;
  std::string str_to_split = "this,is,the,string,to,split";

  boost::algorithm::split(str_vec,
                          str_to_split.substr(1, str_to_split.size()-2),
                          boost::algorithm::is_any_of(","),
                          boost::algorithm::token_compress_on);


  return 0;

编译我做:&gt;&gt; g++ -o foo foo.cpp

这是我的终端输出:

foo.cpp: In function 'int main()':
foo.cpp:11:54: error: invalid initialization of non-const reference type 'std::basic_string<char>&' from an rvalue of type'std::basic_string<char>'
   boost::algorithm::split(str_vec,str_to_split.substr(1, str_to_split.size()-2),boost::algorithm::is_an
                                                      ^
In file included from /usr/include/boost/algorithm/string.hpp:23:0,
                 from foo.cpp:1:
/usr/include/boost/algorithm/string/split.hpp:140:35: note:   initializing argument 2 of 'equenceSequenceT& boost::algorithm::split(SequenceSequenceT&, RangeT&, PredicateT, boost::algorithm::token_compress_mode_type) [with SequenceSequenceT = std::vector<std::basic_string<char> >; RangeT = std::basic_string<char>; PredicateT = boost::algorithm::detail::is_any_ofF<char>]'
         inline SequenceSequenceT& split(
                               ^

【问题讨论】:

很清楚。 Boost 想要一个非常量引用作为它的第二个参数(我想,它会修改它),并且你不能将非常量引用绑定到临时的。 @SergeyA:我永远无法弄清楚为什么它需要一个非常量 ref 或者它为什么要修改拆分函数的输入。 @BarryTheHatchet,也不知道,但是:This function is equivalent to C strtok(来自 Boost),strtok 修改了它的论点。可能有人只是复制行为? 【参考方案1】:

此函数采用std::string&amp; 而不是std::stringconst std::string&amp;。这意味着您必须将.substr 的结果存储在中间变量中,然后将变量传递给boost::algorithm::split。反正代码会更清晰。

FWIW,我不知道为什么这个功能是这样设计的。对我来说似乎很奇怪,但你去吧。

【讨论】:

@dmedine:因此,多年来我的代码库中有一行“额外”的代码!不过,老实说,如果您将str_to_split 设置为您要拆分的实际字符串,并使用str_to_split = str_to_split.substr(...),它可能会更清楚。 @SergeyA:这是个糟糕的主意 @SergeyA:你不认为本地修改 Boost 源是一件可怕的事情吗? @SergeyA: 100% 不可移植性,一旦更新 Boost,您的更改就会丢失,您正在干预您可能不完全理解的代码,您将如何对其进行版本控制(克隆整个 Boost 存储库?ew)您可能会破坏也在您的机器上构建的其他项目,等等等等……这不是修改或扩展 3rd 方库的方式!如果你想包装boost::algorithm::split,那么就这样做,但是为了上帝的缘故,把新函数放在你自己的命名空间中!! Boost code mod 不可能通过我团队的代码审查,除非它是完全、完全不可避免和非常临时的。 @SergeyA for you boost.org/doc/libs/1_60_0/libs/mpl/doc/refmanual/… 是允许具有更多元素的 MPL 容器的正确方法

以上是关于使用 boost::algorithm:string:split 和 std::string 的 g++ 无效初始化错误的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)