如何在 boost 1.55 中使用 boost::split 和 boost::string_ref
How to use boost::split with boost::string_ref in boost 1.55
代码:
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/utility/string_ref.hpp>
int main()
{
boost::string_ref str = "test_the_world";
std::vector<boost::string_ref> strs;
boost::split(strs, str, boost::is_any_of("_"), boost::token_compress_on);
for (auto& v : strs)
{
std::cout << v << std::endl;
}
return 0;
}
错误:
1>C:\boost_1_55_0\boost/range/iterator_range_core.hpp(643): error C2665: 'boost::basic_string_ref<char,std::char_traits<char>>::basic_string_ref' : none of the 4 overloads could convert all the argument types
1> C:\boost_1_55_0\boost/utility/string_ref.hpp(79): could be 'boost::basic_string_ref<char,std::char_traits<char>>::basic_string_ref(const charT *,boost::basic_string_ref<charT,std::char_traits<char>>::size_type)'
1> with
1> [
1> charT=char
1> ]
1> while trying to match the argument list '(const char *, const char *)'
1> C:\boost_1_55_0\boost/algorithm/string/detail/util.hpp(97) : see reference to function template instantiation 'SeqT boost::copy_range<SeqT,boost::iterator_range<const char *>>(const Range &)' being compiled
1> with
1> [
1> SeqT=boost::basic_string_ref<char,std::char_traits<char>>
1> , Range=boost::iterator_range<const char *>
1> ]
1> C:\boost_1_55_0\boost/algorithm/string/detail/util.hpp(96) : while compiling class template member function 'boost::basic_string_ref<char,std::char_traits<char>> boost::algorithm::detail::copy_iterator_rangeF<boost::basic_string_ref<char,std::char_traits<char>>,input_iterator_type>::operator ()(const boost::iterator_range<const char *> &) const'
等等 .. 我怎样才能使这个工作?不明白为什么它不起作用?
Cheap hack:为 string_ref
专门化 copy_range
,因为它不需要迭代器对。
namespace boost
{
template <>
inline string_ref
copy_range<string_ref, iterator_range<char const*>>
( iterator_range<char const*> const& r )
{
return string_ref( begin(r), end(r) - begin(r) );
}
}
Demo.
但是,肯定有更好的解决方案,所以我会继续寻找。
Boost iter_split
非常适合这个,尽管它自然有利于 iterator_range
而不是 string_ref
:Difference between boost::split vs boost::iter_split
using R = boost::iterator_range<std::string::const_iterator>;
using V = std::vector<R>;
V v;
for (auto&& r : iter_split(v, input, token_finder(is_any_of(";"))))
std::cout << r << "\n";
如果你坚持可以调整结果:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed([](R const& r){return boost::string_ref(&*r.begin(), r.size());})
std::cout << r << "\n";
或者如果您没有 c++11 支持:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed(phx::construct<boost::string_ref>(&*phx::begin(_1), phx::size(_1))))
std::cout << r << "\n";
如果您想要 string_ref
个对象的真实向量,请结合 copy_range<vector<string_ref> >()
。
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/phoenix.hpp>
#include <boost/phoenix/stl.hpp>
#include <boost/utility/string_ref.hpp>
#include <iostream>
using namespace boost::algorithm;
namespace phx = boost::phoenix;
using namespace phx::arg_names;
using boost::adaptors::transformed;
int main() {
std::string input = "1;3;5;7";
using boost::string_ref;
using R = boost::iterator_range<std::string::const_iterator>;
using V = std::vector<R>;
V v;
// just the iterator ranges:
for (auto&& r : iter_split(v, input, token_finder(is_any_of(";"))))
std::cout << r << "\n";
// using a lambda to create the string_refs:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed([](R const& r){return string_ref(&*r.begin(), r.size());}))
std::cout << r << "\n";
// c++03 version:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed(phx::construct<string_ref>(&*phx::begin(_1), phx::size(_1))))
std::cout << r << "\n";
}
代码:
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/utility/string_ref.hpp>
int main()
{
boost::string_ref str = "test_the_world";
std::vector<boost::string_ref> strs;
boost::split(strs, str, boost::is_any_of("_"), boost::token_compress_on);
for (auto& v : strs)
{
std::cout << v << std::endl;
}
return 0;
}
错误:
1>C:\boost_1_55_0\boost/range/iterator_range_core.hpp(643): error C2665: 'boost::basic_string_ref<char,std::char_traits<char>>::basic_string_ref' : none of the 4 overloads could convert all the argument types
1> C:\boost_1_55_0\boost/utility/string_ref.hpp(79): could be 'boost::basic_string_ref<char,std::char_traits<char>>::basic_string_ref(const charT *,boost::basic_string_ref<charT,std::char_traits<char>>::size_type)'
1> with
1> [
1> charT=char
1> ]
1> while trying to match the argument list '(const char *, const char *)'
1> C:\boost_1_55_0\boost/algorithm/string/detail/util.hpp(97) : see reference to function template instantiation 'SeqT boost::copy_range<SeqT,boost::iterator_range<const char *>>(const Range &)' being compiled
1> with
1> [
1> SeqT=boost::basic_string_ref<char,std::char_traits<char>>
1> , Range=boost::iterator_range<const char *>
1> ]
1> C:\boost_1_55_0\boost/algorithm/string/detail/util.hpp(96) : while compiling class template member function 'boost::basic_string_ref<char,std::char_traits<char>> boost::algorithm::detail::copy_iterator_rangeF<boost::basic_string_ref<char,std::char_traits<char>>,input_iterator_type>::operator ()(const boost::iterator_range<const char *> &) const'
等等 .. 我怎样才能使这个工作?不明白为什么它不起作用?
Cheap hack:为 string_ref
专门化 copy_range
,因为它不需要迭代器对。
namespace boost
{
template <>
inline string_ref
copy_range<string_ref, iterator_range<char const*>>
( iterator_range<char const*> const& r )
{
return string_ref( begin(r), end(r) - begin(r) );
}
}
Demo.
但是,肯定有更好的解决方案,所以我会继续寻找。
Boost iter_split
非常适合这个,尽管它自然有利于 iterator_range
而不是 string_ref
:Difference between boost::split vs boost::iter_split
using R = boost::iterator_range<std::string::const_iterator>;
using V = std::vector<R>;
V v;
for (auto&& r : iter_split(v, input, token_finder(is_any_of(";"))))
std::cout << r << "\n";
如果你坚持可以调整结果:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed([](R const& r){return boost::string_ref(&*r.begin(), r.size());})
std::cout << r << "\n";
或者如果您没有 c++11 支持:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed(phx::construct<boost::string_ref>(&*phx::begin(_1), phx::size(_1))))
std::cout << r << "\n";
如果您想要 string_ref
个对象的真实向量,请结合 copy_range<vector<string_ref> >()
。
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/finder.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/phoenix.hpp>
#include <boost/phoenix/stl.hpp>
#include <boost/utility/string_ref.hpp>
#include <iostream>
using namespace boost::algorithm;
namespace phx = boost::phoenix;
using namespace phx::arg_names;
using boost::adaptors::transformed;
int main() {
std::string input = "1;3;5;7";
using boost::string_ref;
using R = boost::iterator_range<std::string::const_iterator>;
using V = std::vector<R>;
V v;
// just the iterator ranges:
for (auto&& r : iter_split(v, input, token_finder(is_any_of(";"))))
std::cout << r << "\n";
// using a lambda to create the string_refs:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed([](R const& r){return string_ref(&*r.begin(), r.size());}))
std::cout << r << "\n";
// c++03 version:
for (string_ref&& r : iter_split(v, input, token_finder(is_any_of(";")))
| transformed(phx::construct<string_ref>(&*phx::begin(_1), phx::size(_1))))
std::cout << r << "\n";
}