8

boost 中的 string_ref 和 GSL 中的 string_span 都没有定义采用一对迭代器的构造函数。这个决定的原因是什么?

通常这没什么大不了的,我可以像这样创建 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 中采用一对迭代器

4

3 回答 3

5

boost::string_ref是对字符串的简单引用,其形式为指向具有预定义长度的连续内存块的指针。由于迭代器更为通用,因此您不能假设您的start, finish范围指的是任何类似连续内存块的东西。

另一方面,astd::string可以从迭代器定义的范围构造,因为它只会复制范围的值,而不管底层数据结构是什么。

于 2015-11-17T07:33:18.643 回答
2

我创建的辅助函数,希望其他人能发现这个有用。简要测试 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
于 2016-11-29T00:54:15.033 回答
1

看来我犯了一个错误。gsl::string_span确实有一个带有开始和结束迭代器的构造函数。因此,从迭代器对创建 string_view 没有任何问题,并且缺少它boost::string_ref可能只是一个疏忽。

就我而言,我最终自己继承boost::string_ref并添加了构造函数。

于 2015-11-17T15:44:51.023 回答