从std :: byte迭代器视觉接受std :: string

时间:2018-08-28 15:27:29

标签: c++ gcc visual-c++ clang language-lawyer

此代码在Visual中可以很好地编译,而在GCC或Clang中失败。

我知道从std::bytechar的转换可能是个问题。是禁止提供这种转换,还是视觉上的C ++错误?是否可以接受,并且GCC / Clang中缺少一个不错的功能?

#include <vector>
#include <string>

int main()
{
    std::vector<std::byte> test(10);
    std::string str(test.begin(), test.end());
}

编辑

Microsoft (fixed it)

  

我们已在以后的版本中解决了该问题。现在,MSVC提供了   如下错误:错误C2664:'无效   std :: basic_string,std :: allocator> :: push_back(const   _Elem)':不能使用[将参数1从'std :: byte'转换为'const _Elem'   _Elem = char]

2 个答案:

答案 0 :(得分:2)

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应可从X*i中的Emplace构造。

[container.requirements.general]/15.5指出EmplaceConstructible的意思是

  

T可从Xargs的EmplaceConstructible中,对于零个或多个参数args,意味着以下表达式格式正确:

allocator_traits<A>::construct(m, p, args)

construct[allocator.requirements] - Table 33中定义为

  

效果:在c处构造C类型的对象

     

默认::new ((void*)c)C(forward<Args>(args)...)

因此,目前尚不清楚是否允许。

答案 1 :(得分:1)

Visual C ++错误。 std::byte是一个有范围的枚举,即 ie enum class声明,因此不能转换为char或任何其他算术类型,除非显式强制转换为使用。