2015-11-17 3 views
3

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

Обычно это не имеет большого значения, я могу просто создать 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

+0

Я предполагаю, что ваши итераторы на самом деле 'std :: string :: iterator'? Потому что 'string_ref' ссылается на существующую строку, поэтому вы не можете ее создать из-под воздуха. – MSalters

+0

@MSalters На самом деле, мой итератор уже «boost :: string_ref :: iterator' :). –

+0

Стоит прочитать чат об этом, было сделано в будущей группе предложений std: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/6X6_IjfzdYI, стоит прочитать. – Dam

ответ

0

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

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

3

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

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

+2

Это не совсем убедительный аргумент. Было бы разумно построить 'boost :: string_ref' из' std :: string :: iterator'. Но даже это не допускается. – MSalters

+0

@MSalters Точно, по крайней мере, они должны быть в состоянии принять пару 'boost :: string_ref :: iterator' –

0

Вспомогательная функция, которую я создал, надеюсь, кто-то может найти это полезным. Кратко протестировано MSVC14/boost 1.59

#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<std::iterator_traits<_It>::value_type>; 

    return result_type{ 
     &*begin 
     , (result_type::size_type) 
      std::max( 
       std::distance(begin, end) 
       , (result_type::difference_type)0 
      ) 
    }; 
} // make_string_view