采用迭代器对的 MSVS 的字符串构造函数看起来像
template<class _Iter,
class = enable_if_t<_Is_iterator_v<_Iter>>>
basic_string(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc())
: _Mybase(_Al)
{ // construct from [_First, _Last) with optional allocator
_Tidy_init();
_Adl_verify_range(_First, _Last);
_Construct(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Iter_cat_t<_Iter>());
}
_Construct 最终打来电话
template<class _Iter>
void _Construct(_Iter _First, const _Iter _Last, input_iterator_tag)
{ // initialize from [_First, _Last), input iterators
_TRY_BEGIN
for (; _First != _Last; ++_First)
{
push_back(static_cast<_Elem>(*_First));
}
_CATCH_ALL
_Tidy_deallocate();
_RERAISE;
_CATCH_END
}
重要的一点是push_back(static_cast<_Elem>(*_First));。通常您无法将std::byte 直接分配给另一种类型,因为它是一个作用域枚举,但由于存在static_cast,您可以绕过它。
这就是为什么您可以使用一系列字节来初始化std::string。
也就是说迭代器构造函数需要[sequence.reqmts] - Table 68那个
T 应该是 EmplaceConstructible 到 X 从 *i。
而[container.requirements.general]/15.5 声明EmplaceConstructible 表示
T is EmplaceConstructible into X from args,对于零个或多个参数args,意味着以下表达式是良构的:
allocator_traits<A>::construct(m, p, args)
而construct 在[allocator.requirements] - Table 33 中定义为
效果:在 c 处构造一个 C 类型的对象
默认::new ((void*)c)C(forward<Args>(args)...)
所以目前还不清楚这是否允许。