Почему конструктор string_view не использует пару итераторов

И string_ref в boost, и string_span в GSL не определяют конструктор, который принимает пару итераторов. В чем причина этого решения?

Обычно это не имеет большого значения, я могу просто создать string_ref следующим образом:

boost::string_ref s(start, std::distance(start, finish));

но причина, по которой я хочу, чтобы конструктор использовал пару итераторов, заключается в том, что у меня есть код, который выглядит следующим образом:

template<typename Type, typename Iterator>
void func(const Iterator& begin, const Iterator& end)
{
Type s(begin, end);
//do stuff with s
}

В настоящее время я могу назвать это так:

func<std::string>(start, finish)

Я хочу изменить это на:

func<boost::string_ref>(start, finish) //compile error

но этот код не скомпилируется, потому что отсутствие конструктора, принимающего пару итераторов в string_ref

3

Решение

boost::string_ref простая ссылка на строку в виде указателя на смежный блок памяти с заданной длиной. Поскольку итераторы гораздо более общие, вы не можете предполагать, что ваши start, finish Диапазон относится к чему-либо как непрерывный блок памяти.

С другой стороны, std::string может быть создан из диапазона, определенного Итераторами, потому что он просто сделает копию значений диапазона, независимо от того, что является базовой структурой данных.

3

Другие решения

Вспомогательная функция, которую я создал, надеюсь, кто-то еще может найти это полезным. Кратко протестировано 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
1

Похоже, я ошибаюсь. gsl::string_span У меня есть конструктор, который принимает начальный и конечный итератор. Таким образом, нет ничего проблемного в создании string_view из пар итераторов и его отсутствии в boost::string_ref это, вероятно, просто недосмотр.

В моем случае я в конечном итоге наследую от boost::string_ref и добавить конструктор сам.

0
По вопросам рекламы [email protected]