Both string_ref in boost and string_span in GSL doesn't define constructor that takes a pair of iterator. What is the reason of this decision ?
Usually it's not a big deal, I can just create string_ref like this :
boost::string_ref s(start, std::distance(start, finish));
but the reason I want constructor that take a pair of iterators is because I have code that look like this:
template<typename Type, typename Iterator>
void func(const Iterator& begin, const Iterator& end)
{
Type s(begin, end);
//do stuff with s
}
Currently, I can call it like this :
func<std::string>(start, finish)
I want to change it to :
func<boost::string_ref>(start, finish) //compile error
but that code won't compile because the lack of constructor taking a pair of iterator in string_ref
Conceptually, string_view is only a view of the string and cannot be used to modify the actual string. When a string_view is created, there's no need to copy the data (unlike when you create a copy of a string). Furthermore, in terms of size on the heap, string_view is smaller than std::string .
So, frequently, you can pass string_view by reference and get away with it. But you should pass string_view by value, so that the compiler doesn't have to do those heroics on your behalf. And so that your code-reviewer doesn't have to burn brain cells pondering your unidiomatic decision to pass by reference.
string_view is a slice in an existing buffer, it does not require a memory allocation.
boost::string_ref
is a simple reference to a string in the form of a pointer to a contiguous block of memory with a predefined length. Since iterators are much more generic, you cannot assume that your start, finish
range refers to anything like a contiguous block of memory.
On the other hand, a std::string
can be constructed from a range defined by Iterators because it will simply make a copy of the range's values, regardless of what the underlying data structure is.
Helper function I created, hopefully someone else can find this useful. Briefly tested MSVC14/boost 1.59, MSVC17/boost 1.64, MSVC17/C++17
#include <boost/utility/string_ref.hpp>
// todo: change to std::basic_string_view<charT> in C++17
template <typename charT> using basic_string_view_type = boost::basic_string_ref<charT>;
// Creates a string view from a pair of iterators
// http://stackoverflow.com/q/33750600/882436
template <typename _It>
inline constexpr auto make_string_view( _It begin, _It end )
{
using result_type = basic_string_view_type<typename std::iterator_traits<_It>::value_type>;
return result_type{
( begin != end ) ? &*begin : nullptr
, (typename result_type::size_type)
std::max(
std::distance(begin, end)
, (typename result_type::difference_type)0
)
};
} // make_string_view
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With