Я использую Microsoft Visual Studio Community 2019, V16.5.2. Я хочу проверить инициализацию списка
Пожалуйста, смотрите следующую тестовую программу:
#include <string>
void foo(std::string str) {}
int main() {
foo( {"str1", "str2"} );
return 0;
}
Это компилируется без ошибок и предупреждений. Почему?
Это дает ошибку во время выполнения: Expression: Transposed pointer range
Может кто-нибудь объяснить, что здесь происходит?
Редактировать.
Я разобрал код и запустил его в отладчике
foo( {"str1", "str2"} );
00F739A8 sub esp,1Ch
00F739AB mov esi,esp
00F739AD mov dword ptr [ebp-0C8h],esp
00F739B3 lea ecx,[ebp-0D1h]
00F739B9 call std::allocator<char>::allocator<char> (0F7136Bh)
00F739BE push eax
00F739BF push offset string "str2" (0F84DB8h)
00F739C4 push offset string "str1" (0F84E2Ch)
00F739C9 mov ecx,esi
00F739CB call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> ><char const *,0> (0F71569h)
00F739D0 call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (0F71843h)
00F739D5 add esp,1Ch
Вылетает ли при первом вызове конструктора?
Ответы:
std::string
имеет шаблонный конструктор, который строит строку из пары итератор начала / конца. Строковые литералы в C ++ переходят вconst char*
s. И указатели являются итераторами. Поэтому при инициализации списка был выбран начальный / конечный пары конструктор.Вы получили ошибку во время выполнения, потому что два указателя фактически не создают допустимый диапазон, который не может быть определен во время компиляции (как правило).
источник
<char const *,0>
. Может кто-нибудь, пожалуйста, объясните это?template< InputIt > (InputIt first, InputIt last,...)
конструктора , где параметр шаблонаiter
являетсяconst char*
.... и , видимо , ваша реализация имеет второй целочисленный параметр для какой - то причины?std::string
имеет перегрузку конструктора в видеи это вызывается потому что
"str1"
и"str2"
decay toconst char*
s иconst char*
является приемлемым типом итератора.Вы получаете сбой, потому что «диапазон итераторов», который вы передали функции, недопустим.
источник
Это использовать конструктор с итераторами std :: string (6.).
С помощью [
InputIt
=const char*
].Тогда у вас есть UB, поскольку диапазон
{"str1", "str2"}
недействителен.источник