简体   繁体   English

为什么string_view构造函数不接受一对迭代器

[英]Why string_view constructor doesn't take a pair of iterators

Both string_ref in boost and string_span in GSL doesn't define constructor that takes a pair of iterator. boost中的string_ref和GSL中的string_span都没有定义带有一对迭代器的构造函数。 What is the reason of this decision ? 这个决定的原因是什么?

Usually it's not a big deal, I can just create string_ref like this : 通常这不是什么大问题,我可以像这样创建string_ref:

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 但是该代码将无法编译,因为缺少构造函数在string_ref中使用一对迭代器

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. boost::string_ref是一个字符串的简单引用,其形式为指向具有预定义长度的连续内存块的指针。 Since iterators are much more generic, you cannot assume that your start, finish range refers to anything like a contiguous block of memory. 由于迭代器更通用,因此您不能假设您的start, finish范围指的是类似于连续内存块的任何内容。

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. 另一方面, std::string可以从迭代器定义的范围构造,因为它将简单地复制范围的值,而不管底层数据结构是什么。

Helper function I created, hopefully someone else can find this useful. 我创建的助手功能,希望其他人可以找到这个有用的功能。 Briefly tested MSVC14/boost 1.59, MSVC17/boost 1.64, MSVC17/C++17 简要测试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

Looks like I make a mistake. 看起来我犯了一个错误。 gsl::string_span do have a constructor that takes begin and end iterator. gsl::string_span确实有一个构造函数,它接受开始和结束迭代器。 So, there is nothing problematic with creating string_view from iterator pairs and the lack of it in boost::string_ref is probably just an oversight. 因此,从迭代器对创建string_view没有任何问题,而在boost::string_ref缺少它可能只是一个疏忽。

For my case, I end up inheriting from boost::string_ref and add the constructor myself. 对于我的情况,我最终继承自boost::string_ref并自己添加构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM