Почему конструктор 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 ответа

Решение

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

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

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

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

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