繁体   English   中英

将initializer_list插入std :: vector时“无效的迭代器范围”

[英]“Invalid iterator range” while inserting initializer_list to an std::vector

此代码在Ideone按预期编译并运行正常:

#include <iostream>
#include <string>
#include <vector>

int main() {

    std::vector<std::wstring> strVec;
    strVec.insert(strVec.end(), { L"black", L"white", L"red" });
    strVec.insert(strVec.end(), { L"blue", L"green" }); // STL exception

    for (auto &i : strVec) {
        std::wcout << i << " ";
    }
    return 0;
}

但是,MSVC(Visual Studio 2013)中的“无效迭代器范围”失败。有任何见解吗?

顺便说一句,插入更多的元素,例如在第二个插入,这适用于MSVC:

strVec.insert( strVec.end(), { L"blue", L"green", L"yellow" } );

与容量/大小相关并使一些迭代器无效? 但是第二次insert请求新的迭代器end() ,它必须是有效的,对吗? 或者......它实际上是关于初始化列表?

注意:不在这里寻找变通方法(大量的) - 只是试图弄清楚这是否是特定于MSVC的错误或者合法错误正在发生......

VS 2013选择了重载vector<T>::insert(const_iterator, const T&) ,从一对指针const wchar*, const wchar*构造wstring const wchar*, const wchar*解释为一系列字符的开始和结束; 请注意,宽字符串文字会衰减为const wchar*指针。 这就是为什么只有在尝试精确插入2个元素时才会出现问题的原因。

这是调用堆栈:

msvcp120d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 15 C++
Project1.exe!std::_Debug_range2<wchar_t const *>(const wchar_t * _First, const wchar_t * _Last, const wchar_t * _File, unsigned int _Line, std::random_access_iterator_tag __formal) Line 576   C++
Project1.exe!std::_Debug_range<wchar_t const *>(const wchar_t * _First, const wchar_t * _Last, const wchar_t * _File, unsigned int _Line) Line 584  C++
Project1.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >(const wchar_t * _First, const wchar_t * _Last) Line 860    C++
Project1.exe!main() Line 9  C++

VS 2013是错误的,因为[over.ics.rank]

3 - [...]

  • 列表初始化序列L1是比列表初始化序列L2更好的转换序列,如果:
    • L1转换为std::initializer_list<X>表示某些XL2不[...]

这已在VS2015中修复。

可能会发生这种情况,因为当您编写{ L"blue", L"green" }编译器将它们用作构造值的两个指针( std::wstring )并将其传递给下一个std::vector::insert重载:

insert( const_iterator pos, const T& value ); 

所以从指针L"blue"L"green"运行很可能在程序没有读取权限的地方结束,或者它检查第一个指针是否小于秒,并在它们没有时抛出异常。

暂无
暂无

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

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