为什么 string_view 构造函数不采用一对迭代器
Why string_view constructor doesn't take a pair of iterators
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
中缺少采用一对迭代器的构造函数
boost::string_ref
是对字符串的简单引用,其形式为指向具有预定义长度的 连续 内存块的指针。由于迭代器更通用,您不能假设您的 start, finish
范围指的是连续的内存块之类的东西。
另一方面,std::string
可以从迭代器定义的范围构造,因为它只会复制范围的值,而不管底层数据结构是什么。
看来我弄错了。 gsl::string_span
确实有一个采用开始和结束迭代器的构造函数。因此,从迭代器对创建 string_view 没有任何问题,boost::string_ref
中缺少它可能只是一个疏忽。
对于我的情况,我最终继承自 boost::string_ref
并自己添加构造函数。
我创建的辅助函数,希望其他人能发现它有用。简要测试 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
//
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
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
中缺少采用一对迭代器的构造函数boost::string_ref
是对字符串的简单引用,其形式为指向具有预定义长度的 连续 内存块的指针。由于迭代器更通用,您不能假设您的 start, finish
范围指的是连续的内存块之类的东西。
另一方面,std::string
可以从迭代器定义的范围构造,因为它只会复制范围的值,而不管底层数据结构是什么。
看来我弄错了。 gsl::string_span
确实有一个采用开始和结束迭代器的构造函数。因此,从迭代器对创建 string_view 没有任何问题,boost::string_ref
中缺少它可能只是一个疏忽。
对于我的情况,我最终继承自 boost::string_ref
并自己添加构造函数。
我创建的辅助函数,希望其他人能发现它有用。简要测试 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
//
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