之前在写算法的时候使用VS2008,最近需要往CentOS上部署,需要把代码使用gcc编译。由于在代码中使用了大量的boost库,按理说是应该没有问题的。但是今天出现了一个很奇怪的问题,boost的split函数编译不过去。比如下面的代码片段。
vector<string> vStr;
split(vStr, vPicFiles[i].filename(), is_any_of("_."));
上面的代码使用VS2008的编译器完全无压力,而是用GCC编译器就直接报错。错误信息如下:
F:\BoostTest\BoostTest.cpp|165|error: no matching function for call to 'split(std::vector<std::basic_string<char> >&, boost::filesystem::basic_path<std::basic_string<char>, boost::filesystem::path_traits>::string_type, boost::algorithm::detail::is_any_ofF<char>)'|
Google了N久,找到了一篇文章,地址在下面的参考资料里面。里面有段代码,如下:
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
std::string f()
{
return "";
}
int main()
{
std::vector<std::string> v;
boost::split(v, f(), boost::is_any_of(","));
return 0;
}
这段代码使用Gcc编译后的错误信息是:
split_test.cpp: In function 'int main()':
split_test.cpp:13: error: invalid initialization of non-const
reference of type 'std::string&' from a temporary of type
'std::string'
/usr/include/boost/algorithm/string/split.hpp:143: error: in passing
argument 2 of 'SequenceSequenceT&
boost::algorithm::split(SequenceSequenceT&, RangeT&, PredicateT,
boost::algorithm::token_compress_mode_type) [with SequenceSequenceT =
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >, RangeT =
std::string, PredicateT = boost::algorithm::detail::is_any_ofF<char>]'
后面有位大牛指出了错误所在,他说:
This is because f() is returning a std::string and this is being passed to the RangeT & argument in the split function. Due to C++ rules, performing the T -> T & conversion is invalid. Try defining f() as:
const std::string f()
{
return "";
}
通过上面的信息,我们把程序稍微改造一下,就是对于split的参数,先用一个临时变量存起来,然后再使用split,如下:
string strFileName = pFile.filename();
vector<string> vStr;
split(vStr, strFileName, is_any_of("_."));
然后再编译,OK,没有错误了。看来GCC是要比MS的编译器严格啊。
参考资料
1:http://boost.2283326.n4.nabble.com/no-matching-function-for-call-to-boost-algorithm-split-td2604230.html