std::string vs const std::string& vs std::string_viewЗахват аргументовC++: std::vector.push_back() и классыКонвертация std::string в std::wstringИспользование std::string в dllВключение шаблонов и std::enable_ifИспользование std::move в списках инициализацииКак передать аргумент в std::thread по ссылке?Специализация шаблонной функции для std::stringC++,оптимизация подобия функции strstr(const char*,const char*)Запись текста в std::string дважды. С++Отличие между const string &s и string &s

std::string vs const std::string& vs std::string_view


Захват аргументовC++: std::vector.push_back() и классыКонвертация std::string в std::wstringИспользование std::string в dllВключение шаблонов и std::enable_ifИспользование std::move в списках инициализацииКак передать аргумент в std::thread по ссылке?Специализация шаблонной функции для std::stringC++,оптимизация подобия функции strstr(const char*,const char*)Запись текста в std::string дважды. С++Отличие между const string &s и string &s













2















Что правильнее передавать как аргумент функции(например в конструктор), если там эта строка будет просто скопирована?










поделиться|улучшить этот вопрос


























    2















    Что правильнее передавать как аргумент функции(например в конструктор), если там эта строка будет просто скопирована?










    поделиться|улучшить этот вопрос
























      2












      2








      2


      1






      Что правильнее передавать как аргумент функции(например в конструктор), если там эта строка будет просто скопирована?










      поделиться|улучшить этот вопрос














      Что правильнее передавать как аргумент функции(например в конструктор), если там эта строка будет просто скопирована?







      c++






      поделиться|улучшить этот вопрос













      поделиться|улучшить этот вопрос











      поделиться|улучшить этот вопрос




      поделиться|улучшить этот вопрос










      задан 9 часов назад









      tim barstim bars

      607




      607




















          3 ответа
          3






          текущие

          по дате публикации

          голоса


















          1














          Использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий. И это относится не только к std::string и std::string_view



          Для начала определимся с реализацией наших сущностей. Пусть std::string построен на трех указателях по 4 байта каждый (или указатель и два размера):



          class string

          //...
          pointer * m_begin; //Начало строки
          pointer * m_end; //Указатель за последний элемент
          pointer * m_end_of_storage; //Указатель за конец выделенной памяти
          ;


          std::string_view при этом реализован с помощью двух указателей (или указатель и размер):



          class string_view

          //...
          pointer m_data; //Указатель на начало данных
          pointer m_end; //Указатель за конец данных
          ;


          Упрощенно рассмотрим три версии простого кода:



          void other(std::string); //<-- функция, в которую всегда передается копия.

          void run(string_view v) //<-- Функция, которая вызывает функцию other

          //т.е. эта функция делает ту самую копию объекта
          other(v);


          void general(string str)

          //А из этой функции в функцию run передается строка
          other(str);



          Что будет сгенерировано компилятором и как рассматривать не будем, т.к. это сильно зависит от компилятора и параметров компиляции, но постараемся посмотреть что может быть и как.



          В нашем случае other передает копию string_view, т.е. general копирует два указателя (не говорим о возможности вызова конструктора копирования, подразумевая, что он самый тривиальный и в результирующем коде приведет просто к копированию двух членов класса). Затем строка копируется из string_view. Ничего сложного.



          Теперь возьмем тот же код, но при этом run будет принимать ссылку на string.



          void run(string const & v)

          other(v);


          void general(string str)

          other(str);
          //str используется, её нельзя перемещать в other



          Да, Вы правы, передача ссылки в функцию run - быстрая операция, можно считать, что это копирование указателя. Но у передачи ссылки есть и минусы. Один из них - функция run обращается к строке через ссылку, т.е. появляется дополнительный уровень косвенности, который может вылиться в большие затраты, чем "лишнее" копирование указателя в версии функции, принимающей string_view.



          Теперь рассмотрим третий вариант функции run:



          void run(string v)

          other(std::move(v));



          В данном случае копирование строки происходит еще в функции general (причем мы не перемещаем параметр str, т.к. он где-то там еще нужен далее). Затем функция run перемещает объект v в параметр функции other, а это в нашем случае приводит к копированию трех указателей и занулению старых. Очевидно, что в этом случае операций намного больше, чем со string_view, и, вполне вероятно, что косвенное обращение будет тоже быстрее. То есть это может быть самым тормознутым вариантом.



          А теперь представим, такую ситуацию:



          void run(string const &); //<-- имеется такая run
          void run(string_view); //или такая, нам без разницы

          class SomeClass

          string m_text;
          mutex m_mutex;
          void SomeClass::call()

          //Мы знаем, что run делает копию строки,
          //и запускает поток для её обработки
          lock_quard<mutex> locker;//объект у нас защищен мьютексом
          run(m_text);//Где-то там строка копируется и запускается новый поток
          //мы не знаем точный момент, когда строка скопируется,
          //поэтому вынуждены ждать выполнения run под защитой мьютекса,
          //т.к. в other содержаться указатели на защищенные члены нашего класса.
          //Вполне вероятно, что в этот момент другие
          //потоки уже хотят работать с нашим объектом,
          //но не могут, т.к. мьютекс захвачен.

          ;


          Я в комментариях описал проблему. А теперь возьмем ситуацию с копированием и перемещением:



          void run(string); //<-- теперь run принимает копию

          class SomeClass

          //..
          void SomeClass::call()

          //Мы знаем, что run принимает копию строки
          //и запускает поток для её обработки
          unique_lock<mutex> locker;//объект у нас защищен мьютексом
          string text_copy = m_text;//Под защитой выполняем копирование строки
          locker.unlock();//И разблокируем мьютекс, т.к.
          run(std::move(text_copy));//нам уже без разницы что-том делает run,
          //копия данных для него уже создана и другим потокам можно дать доступ к объекту

          ;


          У string_view при этом тоже имеются свои прелести. string_view в принципе не привязан к string - это просто данные и их размер. Т.е. string_view может работать не только с string:



          void run(string_view v);

          void general(string str)

          other(str);//ok


          void general(char const * str, size_t len)

          other(string_view(str, len));//ok


          void general(char const * str)

          other(string_view(str));//ok


          void general(std::vector<char> const & v)

          other(string_view(v.data(), v.size()));//ok



          В случае передачи ссылки придется сделать лишнюю копию строки, в случае передачи копии строки это не страшно, т.к. копия будет перемещена, но это всё равно может быть дороже. Однако, копия строки с перемещением может быть дешевле string_view, если, например для создания string_view потребуется сначала создать строку или какой-то другой буфер с данными. В таком случае будет лучше создать строку и переместить её.



          Но оптимизации также могут перевернуть всё с ног на голову. Когда нужно сделать копию строки, кажется, что это приведет к аллокации памяти и всё это будет медленно. В общем случае это верно, но есть такая штука, как SSO (small string optimization), которая позволяет хранить маленькие строки прямо в объекте string, используя сам объект как буфер для строки. В случае применения такой оптимизации копирование может оказаться равноценно или даже дешевле перемещения.



          То есть создав копию в вызывающей функции и переместив строку в вызываемую функцию, Вы если и потеряете скорость, то очень немного. Но это всё относится к ситуации, когда нужна копия на вызываемой стороне. Если же копия не нужна, то вариантов также масса.




          а для чего тогда стоит использовать string_view?




          string_view нужен как раз тогда, когда копия строки не нужна, но нужно сослаться на какое-то место и с ним работать как со строкой. Ранее нужно было либо писать свою "обертку" подобную string_view, либо копировать нужные данные из исходной строки и работать с ними.



          Всё сказанное выше весьма условно и служит только для демонстрации различных ситуаций.



          Как видите, применение того или иного средства полностью зависит от конкретных условий использования, применяемых алгоритмов, оптимизаций компилятора, устройства библиотеки, платформы на которой всё это работает и т.д., поэтому закончу тем, с чего начал - использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий.






          поделиться|улучшить этот ответ
































            2














            Просто std::string. А потом вместо компирования - перемещать через std::move.






            поделиться|улучшить этот ответ























            • а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

              – tim bars
              9 часов назад












            • это всё весьма и весьма сомнительно.

              – Croessmah
              9 часов назад











            • @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

              – HolyBlackCat
              8 часов назад












            • @Croessmah Расска́жите подробнее?

              – HolyBlackCat
              8 часов назад


















            1















            1. Если строка будет "просто скопирована", то вам следует реализовывать либо "ленивый" вариант семантики перемещения (передавать std::string по значению и затем делать из него перемещение), либо "полный" вариант семантики перемещения (писать две перегруженных функции: для const std::string & и для std::string &&), либо, возможно, реализовать forwarding (писать шаблонную функцию, принимающую универсальную сслыку и делающую std::forward в вашу копию).



              См. https://ru.stackoverflow.com/a/822789/182825



            2. std::string_view уместен везде, где вы будете просто анализировать строку, т.е. он является заменителем const std:string & в ситуациях, когда копирование не будет делаться.






            поделиться|улучшить этот ответ






















              Ваш ответ






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "609"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "на платформе u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "Пользовательский контент попадает под действие u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003eлицензии cc by-sa 3.0u003c/au003e с u003ca href="https://stackoverflow.com/legal/content-policy"u003eуказанием ссылки на источникu003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              черновик сохранён

              черновик удалён


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fru.stackoverflow.com%2fquestions%2f954084%2fstdstring-vs-const-stdstring-vs-stdstring-view%23new-answer', 'question_page');

              );

              Отправить без регистрации















              Необходима, но никому не показывается

























              3 ответа
              3






              текущие

              по дате публикации

              голоса








              3 ответа
              3






              текущие

              по дате публикации

              голоса









              текущие

              по дате публикации

              голоса






              текущие

              по дате публикации

              голоса









              1














              Использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий. И это относится не только к std::string и std::string_view



              Для начала определимся с реализацией наших сущностей. Пусть std::string построен на трех указателях по 4 байта каждый (или указатель и два размера):



              class string

              //...
              pointer * m_begin; //Начало строки
              pointer * m_end; //Указатель за последний элемент
              pointer * m_end_of_storage; //Указатель за конец выделенной памяти
              ;


              std::string_view при этом реализован с помощью двух указателей (или указатель и размер):



              class string_view

              //...
              pointer m_data; //Указатель на начало данных
              pointer m_end; //Указатель за конец данных
              ;


              Упрощенно рассмотрим три версии простого кода:



              void other(std::string); //<-- функция, в которую всегда передается копия.

              void run(string_view v) //<-- Функция, которая вызывает функцию other

              //т.е. эта функция делает ту самую копию объекта
              other(v);


              void general(string str)

              //А из этой функции в функцию run передается строка
              other(str);



              Что будет сгенерировано компилятором и как рассматривать не будем, т.к. это сильно зависит от компилятора и параметров компиляции, но постараемся посмотреть что может быть и как.



              В нашем случае other передает копию string_view, т.е. general копирует два указателя (не говорим о возможности вызова конструктора копирования, подразумевая, что он самый тривиальный и в результирующем коде приведет просто к копированию двух членов класса). Затем строка копируется из string_view. Ничего сложного.



              Теперь возьмем тот же код, но при этом run будет принимать ссылку на string.



              void run(string const & v)

              other(v);


              void general(string str)

              other(str);
              //str используется, её нельзя перемещать в other



              Да, Вы правы, передача ссылки в функцию run - быстрая операция, можно считать, что это копирование указателя. Но у передачи ссылки есть и минусы. Один из них - функция run обращается к строке через ссылку, т.е. появляется дополнительный уровень косвенности, который может вылиться в большие затраты, чем "лишнее" копирование указателя в версии функции, принимающей string_view.



              Теперь рассмотрим третий вариант функции run:



              void run(string v)

              other(std::move(v));



              В данном случае копирование строки происходит еще в функции general (причем мы не перемещаем параметр str, т.к. он где-то там еще нужен далее). Затем функция run перемещает объект v в параметр функции other, а это в нашем случае приводит к копированию трех указателей и занулению старых. Очевидно, что в этом случае операций намного больше, чем со string_view, и, вполне вероятно, что косвенное обращение будет тоже быстрее. То есть это может быть самым тормознутым вариантом.



              А теперь представим, такую ситуацию:



              void run(string const &); //<-- имеется такая run
              void run(string_view); //или такая, нам без разницы

              class SomeClass

              string m_text;
              mutex m_mutex;
              void SomeClass::call()

              //Мы знаем, что run делает копию строки,
              //и запускает поток для её обработки
              lock_quard<mutex> locker;//объект у нас защищен мьютексом
              run(m_text);//Где-то там строка копируется и запускается новый поток
              //мы не знаем точный момент, когда строка скопируется,
              //поэтому вынуждены ждать выполнения run под защитой мьютекса,
              //т.к. в other содержаться указатели на защищенные члены нашего класса.
              //Вполне вероятно, что в этот момент другие
              //потоки уже хотят работать с нашим объектом,
              //но не могут, т.к. мьютекс захвачен.

              ;


              Я в комментариях описал проблему. А теперь возьмем ситуацию с копированием и перемещением:



              void run(string); //<-- теперь run принимает копию

              class SomeClass

              //..
              void SomeClass::call()

              //Мы знаем, что run принимает копию строки
              //и запускает поток для её обработки
              unique_lock<mutex> locker;//объект у нас защищен мьютексом
              string text_copy = m_text;//Под защитой выполняем копирование строки
              locker.unlock();//И разблокируем мьютекс, т.к.
              run(std::move(text_copy));//нам уже без разницы что-том делает run,
              //копия данных для него уже создана и другим потокам можно дать доступ к объекту

              ;


              У string_view при этом тоже имеются свои прелести. string_view в принципе не привязан к string - это просто данные и их размер. Т.е. string_view может работать не только с string:



              void run(string_view v);

              void general(string str)

              other(str);//ok


              void general(char const * str, size_t len)

              other(string_view(str, len));//ok


              void general(char const * str)

              other(string_view(str));//ok


              void general(std::vector<char> const & v)

              other(string_view(v.data(), v.size()));//ok



              В случае передачи ссылки придется сделать лишнюю копию строки, в случае передачи копии строки это не страшно, т.к. копия будет перемещена, но это всё равно может быть дороже. Однако, копия строки с перемещением может быть дешевле string_view, если, например для создания string_view потребуется сначала создать строку или какой-то другой буфер с данными. В таком случае будет лучше создать строку и переместить её.



              Но оптимизации также могут перевернуть всё с ног на голову. Когда нужно сделать копию строки, кажется, что это приведет к аллокации памяти и всё это будет медленно. В общем случае это верно, но есть такая штука, как SSO (small string optimization), которая позволяет хранить маленькие строки прямо в объекте string, используя сам объект как буфер для строки. В случае применения такой оптимизации копирование может оказаться равноценно или даже дешевле перемещения.



              То есть создав копию в вызывающей функции и переместив строку в вызываемую функцию, Вы если и потеряете скорость, то очень немного. Но это всё относится к ситуации, когда нужна копия на вызываемой стороне. Если же копия не нужна, то вариантов также масса.




              а для чего тогда стоит использовать string_view?




              string_view нужен как раз тогда, когда копия строки не нужна, но нужно сослаться на какое-то место и с ним работать как со строкой. Ранее нужно было либо писать свою "обертку" подобную string_view, либо копировать нужные данные из исходной строки и работать с ними.



              Всё сказанное выше весьма условно и служит только для демонстрации различных ситуаций.



              Как видите, применение того или иного средства полностью зависит от конкретных условий использования, применяемых алгоритмов, оптимизаций компилятора, устройства библиотеки, платформы на которой всё это работает и т.д., поэтому закончу тем, с чего начал - использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий.






              поделиться|улучшить этот ответ





























                1














                Использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий. И это относится не только к std::string и std::string_view



                Для начала определимся с реализацией наших сущностей. Пусть std::string построен на трех указателях по 4 байта каждый (или указатель и два размера):



                class string

                //...
                pointer * m_begin; //Начало строки
                pointer * m_end; //Указатель за последний элемент
                pointer * m_end_of_storage; //Указатель за конец выделенной памяти
                ;


                std::string_view при этом реализован с помощью двух указателей (или указатель и размер):



                class string_view

                //...
                pointer m_data; //Указатель на начало данных
                pointer m_end; //Указатель за конец данных
                ;


                Упрощенно рассмотрим три версии простого кода:



                void other(std::string); //<-- функция, в которую всегда передается копия.

                void run(string_view v) //<-- Функция, которая вызывает функцию other

                //т.е. эта функция делает ту самую копию объекта
                other(v);


                void general(string str)

                //А из этой функции в функцию run передается строка
                other(str);



                Что будет сгенерировано компилятором и как рассматривать не будем, т.к. это сильно зависит от компилятора и параметров компиляции, но постараемся посмотреть что может быть и как.



                В нашем случае other передает копию string_view, т.е. general копирует два указателя (не говорим о возможности вызова конструктора копирования, подразумевая, что он самый тривиальный и в результирующем коде приведет просто к копированию двух членов класса). Затем строка копируется из string_view. Ничего сложного.



                Теперь возьмем тот же код, но при этом run будет принимать ссылку на string.



                void run(string const & v)

                other(v);


                void general(string str)

                other(str);
                //str используется, её нельзя перемещать в other



                Да, Вы правы, передача ссылки в функцию run - быстрая операция, можно считать, что это копирование указателя. Но у передачи ссылки есть и минусы. Один из них - функция run обращается к строке через ссылку, т.е. появляется дополнительный уровень косвенности, который может вылиться в большие затраты, чем "лишнее" копирование указателя в версии функции, принимающей string_view.



                Теперь рассмотрим третий вариант функции run:



                void run(string v)

                other(std::move(v));



                В данном случае копирование строки происходит еще в функции general (причем мы не перемещаем параметр str, т.к. он где-то там еще нужен далее). Затем функция run перемещает объект v в параметр функции other, а это в нашем случае приводит к копированию трех указателей и занулению старых. Очевидно, что в этом случае операций намного больше, чем со string_view, и, вполне вероятно, что косвенное обращение будет тоже быстрее. То есть это может быть самым тормознутым вариантом.



                А теперь представим, такую ситуацию:



                void run(string const &); //<-- имеется такая run
                void run(string_view); //или такая, нам без разницы

                class SomeClass

                string m_text;
                mutex m_mutex;
                void SomeClass::call()

                //Мы знаем, что run делает копию строки,
                //и запускает поток для её обработки
                lock_quard<mutex> locker;//объект у нас защищен мьютексом
                run(m_text);//Где-то там строка копируется и запускается новый поток
                //мы не знаем точный момент, когда строка скопируется,
                //поэтому вынуждены ждать выполнения run под защитой мьютекса,
                //т.к. в other содержаться указатели на защищенные члены нашего класса.
                //Вполне вероятно, что в этот момент другие
                //потоки уже хотят работать с нашим объектом,
                //но не могут, т.к. мьютекс захвачен.

                ;


                Я в комментариях описал проблему. А теперь возьмем ситуацию с копированием и перемещением:



                void run(string); //<-- теперь run принимает копию

                class SomeClass

                //..
                void SomeClass::call()

                //Мы знаем, что run принимает копию строки
                //и запускает поток для её обработки
                unique_lock<mutex> locker;//объект у нас защищен мьютексом
                string text_copy = m_text;//Под защитой выполняем копирование строки
                locker.unlock();//И разблокируем мьютекс, т.к.
                run(std::move(text_copy));//нам уже без разницы что-том делает run,
                //копия данных для него уже создана и другим потокам можно дать доступ к объекту

                ;


                У string_view при этом тоже имеются свои прелести. string_view в принципе не привязан к string - это просто данные и их размер. Т.е. string_view может работать не только с string:



                void run(string_view v);

                void general(string str)

                other(str);//ok


                void general(char const * str, size_t len)

                other(string_view(str, len));//ok


                void general(char const * str)

                other(string_view(str));//ok


                void general(std::vector<char> const & v)

                other(string_view(v.data(), v.size()));//ok



                В случае передачи ссылки придется сделать лишнюю копию строки, в случае передачи копии строки это не страшно, т.к. копия будет перемещена, но это всё равно может быть дороже. Однако, копия строки с перемещением может быть дешевле string_view, если, например для создания string_view потребуется сначала создать строку или какой-то другой буфер с данными. В таком случае будет лучше создать строку и переместить её.



                Но оптимизации также могут перевернуть всё с ног на голову. Когда нужно сделать копию строки, кажется, что это приведет к аллокации памяти и всё это будет медленно. В общем случае это верно, но есть такая штука, как SSO (small string optimization), которая позволяет хранить маленькие строки прямо в объекте string, используя сам объект как буфер для строки. В случае применения такой оптимизации копирование может оказаться равноценно или даже дешевле перемещения.



                То есть создав копию в вызывающей функции и переместив строку в вызываемую функцию, Вы если и потеряете скорость, то очень немного. Но это всё относится к ситуации, когда нужна копия на вызываемой стороне. Если же копия не нужна, то вариантов также масса.




                а для чего тогда стоит использовать string_view?




                string_view нужен как раз тогда, когда копия строки не нужна, но нужно сослаться на какое-то место и с ним работать как со строкой. Ранее нужно было либо писать свою "обертку" подобную string_view, либо копировать нужные данные из исходной строки и работать с ними.



                Всё сказанное выше весьма условно и служит только для демонстрации различных ситуаций.



                Как видите, применение того или иного средства полностью зависит от конкретных условий использования, применяемых алгоритмов, оптимизаций компилятора, устройства библиотеки, платформы на которой всё это работает и т.д., поэтому закончу тем, с чего начал - использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий.






                поделиться|улучшить этот ответ



























                  1












                  1








                  1







                  Использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий. И это относится не только к std::string и std::string_view



                  Для начала определимся с реализацией наших сущностей. Пусть std::string построен на трех указателях по 4 байта каждый (или указатель и два размера):



                  class string

                  //...
                  pointer * m_begin; //Начало строки
                  pointer * m_end; //Указатель за последний элемент
                  pointer * m_end_of_storage; //Указатель за конец выделенной памяти
                  ;


                  std::string_view при этом реализован с помощью двух указателей (или указатель и размер):



                  class string_view

                  //...
                  pointer m_data; //Указатель на начало данных
                  pointer m_end; //Указатель за конец данных
                  ;


                  Упрощенно рассмотрим три версии простого кода:



                  void other(std::string); //<-- функция, в которую всегда передается копия.

                  void run(string_view v) //<-- Функция, которая вызывает функцию other

                  //т.е. эта функция делает ту самую копию объекта
                  other(v);


                  void general(string str)

                  //А из этой функции в функцию run передается строка
                  other(str);



                  Что будет сгенерировано компилятором и как рассматривать не будем, т.к. это сильно зависит от компилятора и параметров компиляции, но постараемся посмотреть что может быть и как.



                  В нашем случае other передает копию string_view, т.е. general копирует два указателя (не говорим о возможности вызова конструктора копирования, подразумевая, что он самый тривиальный и в результирующем коде приведет просто к копированию двух членов класса). Затем строка копируется из string_view. Ничего сложного.



                  Теперь возьмем тот же код, но при этом run будет принимать ссылку на string.



                  void run(string const & v)

                  other(v);


                  void general(string str)

                  other(str);
                  //str используется, её нельзя перемещать в other



                  Да, Вы правы, передача ссылки в функцию run - быстрая операция, можно считать, что это копирование указателя. Но у передачи ссылки есть и минусы. Один из них - функция run обращается к строке через ссылку, т.е. появляется дополнительный уровень косвенности, который может вылиться в большие затраты, чем "лишнее" копирование указателя в версии функции, принимающей string_view.



                  Теперь рассмотрим третий вариант функции run:



                  void run(string v)

                  other(std::move(v));



                  В данном случае копирование строки происходит еще в функции general (причем мы не перемещаем параметр str, т.к. он где-то там еще нужен далее). Затем функция run перемещает объект v в параметр функции other, а это в нашем случае приводит к копированию трех указателей и занулению старых. Очевидно, что в этом случае операций намного больше, чем со string_view, и, вполне вероятно, что косвенное обращение будет тоже быстрее. То есть это может быть самым тормознутым вариантом.



                  А теперь представим, такую ситуацию:



                  void run(string const &); //<-- имеется такая run
                  void run(string_view); //или такая, нам без разницы

                  class SomeClass

                  string m_text;
                  mutex m_mutex;
                  void SomeClass::call()

                  //Мы знаем, что run делает копию строки,
                  //и запускает поток для её обработки
                  lock_quard<mutex> locker;//объект у нас защищен мьютексом
                  run(m_text);//Где-то там строка копируется и запускается новый поток
                  //мы не знаем точный момент, когда строка скопируется,
                  //поэтому вынуждены ждать выполнения run под защитой мьютекса,
                  //т.к. в other содержаться указатели на защищенные члены нашего класса.
                  //Вполне вероятно, что в этот момент другие
                  //потоки уже хотят работать с нашим объектом,
                  //но не могут, т.к. мьютекс захвачен.

                  ;


                  Я в комментариях описал проблему. А теперь возьмем ситуацию с копированием и перемещением:



                  void run(string); //<-- теперь run принимает копию

                  class SomeClass

                  //..
                  void SomeClass::call()

                  //Мы знаем, что run принимает копию строки
                  //и запускает поток для её обработки
                  unique_lock<mutex> locker;//объект у нас защищен мьютексом
                  string text_copy = m_text;//Под защитой выполняем копирование строки
                  locker.unlock();//И разблокируем мьютекс, т.к.
                  run(std::move(text_copy));//нам уже без разницы что-том делает run,
                  //копия данных для него уже создана и другим потокам можно дать доступ к объекту

                  ;


                  У string_view при этом тоже имеются свои прелести. string_view в принципе не привязан к string - это просто данные и их размер. Т.е. string_view может работать не только с string:



                  void run(string_view v);

                  void general(string str)

                  other(str);//ok


                  void general(char const * str, size_t len)

                  other(string_view(str, len));//ok


                  void general(char const * str)

                  other(string_view(str));//ok


                  void general(std::vector<char> const & v)

                  other(string_view(v.data(), v.size()));//ok



                  В случае передачи ссылки придется сделать лишнюю копию строки, в случае передачи копии строки это не страшно, т.к. копия будет перемещена, но это всё равно может быть дороже. Однако, копия строки с перемещением может быть дешевле string_view, если, например для создания string_view потребуется сначала создать строку или какой-то другой буфер с данными. В таком случае будет лучше создать строку и переместить её.



                  Но оптимизации также могут перевернуть всё с ног на голову. Когда нужно сделать копию строки, кажется, что это приведет к аллокации памяти и всё это будет медленно. В общем случае это верно, но есть такая штука, как SSO (small string optimization), которая позволяет хранить маленькие строки прямо в объекте string, используя сам объект как буфер для строки. В случае применения такой оптимизации копирование может оказаться равноценно или даже дешевле перемещения.



                  То есть создав копию в вызывающей функции и переместив строку в вызываемую функцию, Вы если и потеряете скорость, то очень немного. Но это всё относится к ситуации, когда нужна копия на вызываемой стороне. Если же копия не нужна, то вариантов также масса.




                  а для чего тогда стоит использовать string_view?




                  string_view нужен как раз тогда, когда копия строки не нужна, но нужно сослаться на какое-то место и с ним работать как со строкой. Ранее нужно было либо писать свою "обертку" подобную string_view, либо копировать нужные данные из исходной строки и работать с ними.



                  Всё сказанное выше весьма условно и служит только для демонстрации различных ситуаций.



                  Как видите, применение того или иного средства полностью зависит от конкретных условий использования, применяемых алгоритмов, оптимизаций компилятора, устройства библиотеки, платформы на которой всё это работает и т.д., поэтому закончу тем, с чего начал - использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий.






                  поделиться|улучшить этот ответ















                  Использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий. И это относится не только к std::string и std::string_view



                  Для начала определимся с реализацией наших сущностей. Пусть std::string построен на трех указателях по 4 байта каждый (или указатель и два размера):



                  class string

                  //...
                  pointer * m_begin; //Начало строки
                  pointer * m_end; //Указатель за последний элемент
                  pointer * m_end_of_storage; //Указатель за конец выделенной памяти
                  ;


                  std::string_view при этом реализован с помощью двух указателей (или указатель и размер):



                  class string_view

                  //...
                  pointer m_data; //Указатель на начало данных
                  pointer m_end; //Указатель за конец данных
                  ;


                  Упрощенно рассмотрим три версии простого кода:



                  void other(std::string); //<-- функция, в которую всегда передается копия.

                  void run(string_view v) //<-- Функция, которая вызывает функцию other

                  //т.е. эта функция делает ту самую копию объекта
                  other(v);


                  void general(string str)

                  //А из этой функции в функцию run передается строка
                  other(str);



                  Что будет сгенерировано компилятором и как рассматривать не будем, т.к. это сильно зависит от компилятора и параметров компиляции, но постараемся посмотреть что может быть и как.



                  В нашем случае other передает копию string_view, т.е. general копирует два указателя (не говорим о возможности вызова конструктора копирования, подразумевая, что он самый тривиальный и в результирующем коде приведет просто к копированию двух членов класса). Затем строка копируется из string_view. Ничего сложного.



                  Теперь возьмем тот же код, но при этом run будет принимать ссылку на string.



                  void run(string const & v)

                  other(v);


                  void general(string str)

                  other(str);
                  //str используется, её нельзя перемещать в other



                  Да, Вы правы, передача ссылки в функцию run - быстрая операция, можно считать, что это копирование указателя. Но у передачи ссылки есть и минусы. Один из них - функция run обращается к строке через ссылку, т.е. появляется дополнительный уровень косвенности, который может вылиться в большие затраты, чем "лишнее" копирование указателя в версии функции, принимающей string_view.



                  Теперь рассмотрим третий вариант функции run:



                  void run(string v)

                  other(std::move(v));



                  В данном случае копирование строки происходит еще в функции general (причем мы не перемещаем параметр str, т.к. он где-то там еще нужен далее). Затем функция run перемещает объект v в параметр функции other, а это в нашем случае приводит к копированию трех указателей и занулению старых. Очевидно, что в этом случае операций намного больше, чем со string_view, и, вполне вероятно, что косвенное обращение будет тоже быстрее. То есть это может быть самым тормознутым вариантом.



                  А теперь представим, такую ситуацию:



                  void run(string const &); //<-- имеется такая run
                  void run(string_view); //или такая, нам без разницы

                  class SomeClass

                  string m_text;
                  mutex m_mutex;
                  void SomeClass::call()

                  //Мы знаем, что run делает копию строки,
                  //и запускает поток для её обработки
                  lock_quard<mutex> locker;//объект у нас защищен мьютексом
                  run(m_text);//Где-то там строка копируется и запускается новый поток
                  //мы не знаем точный момент, когда строка скопируется,
                  //поэтому вынуждены ждать выполнения run под защитой мьютекса,
                  //т.к. в other содержаться указатели на защищенные члены нашего класса.
                  //Вполне вероятно, что в этот момент другие
                  //потоки уже хотят работать с нашим объектом,
                  //но не могут, т.к. мьютекс захвачен.

                  ;


                  Я в комментариях описал проблему. А теперь возьмем ситуацию с копированием и перемещением:



                  void run(string); //<-- теперь run принимает копию

                  class SomeClass

                  //..
                  void SomeClass::call()

                  //Мы знаем, что run принимает копию строки
                  //и запускает поток для её обработки
                  unique_lock<mutex> locker;//объект у нас защищен мьютексом
                  string text_copy = m_text;//Под защитой выполняем копирование строки
                  locker.unlock();//И разблокируем мьютекс, т.к.
                  run(std::move(text_copy));//нам уже без разницы что-том делает run,
                  //копия данных для него уже создана и другим потокам можно дать доступ к объекту

                  ;


                  У string_view при этом тоже имеются свои прелести. string_view в принципе не привязан к string - это просто данные и их размер. Т.е. string_view может работать не только с string:



                  void run(string_view v);

                  void general(string str)

                  other(str);//ok


                  void general(char const * str, size_t len)

                  other(string_view(str, len));//ok


                  void general(char const * str)

                  other(string_view(str));//ok


                  void general(std::vector<char> const & v)

                  other(string_view(v.data(), v.size()));//ok



                  В случае передачи ссылки придется сделать лишнюю копию строки, в случае передачи копии строки это не страшно, т.к. копия будет перемещена, но это всё равно может быть дороже. Однако, копия строки с перемещением может быть дешевле string_view, если, например для создания string_view потребуется сначала создать строку или какой-то другой буфер с данными. В таком случае будет лучше создать строку и переместить её.



                  Но оптимизации также могут перевернуть всё с ног на голову. Когда нужно сделать копию строки, кажется, что это приведет к аллокации памяти и всё это будет медленно. В общем случае это верно, но есть такая штука, как SSO (small string optimization), которая позволяет хранить маленькие строки прямо в объекте string, используя сам объект как буфер для строки. В случае применения такой оптимизации копирование может оказаться равноценно или даже дешевле перемещения.



                  То есть создав копию в вызывающей функции и переместив строку в вызываемую функцию, Вы если и потеряете скорость, то очень немного. Но это всё относится к ситуации, когда нужна копия на вызываемой стороне. Если же копия не нужна, то вариантов также масса.




                  а для чего тогда стоит использовать string_view?




                  string_view нужен как раз тогда, когда копия строки не нужна, но нужно сослаться на какое-то место и с ним работать как со строкой. Ранее нужно было либо писать свою "обертку" подобную string_view, либо копировать нужные данные из исходной строки и работать с ними.



                  Всё сказанное выше весьма условно и служит только для демонстрации различных ситуаций.



                  Как видите, применение того или иного средства полностью зависит от конкретных условий использования, применяемых алгоритмов, оптимизаций компилятора, устройства библиотеки, платформы на которой всё это работает и т.д., поэтому закончу тем, с чего начал - использование любого из альтернативных средств очень сильно зависит от ситуации, и выбирается исходя из конкретных условий.







                  поделиться|улучшить этот ответ














                  поделиться|улучшить этот ответ



                  поделиться|улучшить этот ответ








                  изменён 6 часов назад

























                  ответ дан 6 часов назад









                  CroessmahCroessmah

                  3,973717




                  3,973717























                      2














                      Просто std::string. А потом вместо компирования - перемещать через std::move.






                      поделиться|улучшить этот ответ























                      • а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                        – tim bars
                        9 часов назад












                      • это всё весьма и весьма сомнительно.

                        – Croessmah
                        9 часов назад











                      • @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                        – HolyBlackCat
                        8 часов назад












                      • @Croessmah Расска́жите подробнее?

                        – HolyBlackCat
                        8 часов назад















                      2














                      Просто std::string. А потом вместо компирования - перемещать через std::move.






                      поделиться|улучшить этот ответ























                      • а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                        – tim bars
                        9 часов назад












                      • это всё весьма и весьма сомнительно.

                        – Croessmah
                        9 часов назад











                      • @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                        – HolyBlackCat
                        8 часов назад












                      • @Croessmah Расска́жите подробнее?

                        – HolyBlackCat
                        8 часов назад













                      2












                      2








                      2







                      Просто std::string. А потом вместо компирования - перемещать через std::move.






                      поделиться|улучшить этот ответ













                      Просто std::string. А потом вместо компирования - перемещать через std::move.







                      поделиться|улучшить этот ответ












                      поделиться|улучшить этот ответ



                      поделиться|улучшить этот ответ










                      ответ дан 9 часов назад









                      HolyBlackCatHolyBlackCat

                      5,6041514




                      5,6041514












                      • а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                        – tim bars
                        9 часов назад












                      • это всё весьма и весьма сомнительно.

                        – Croessmah
                        9 часов назад











                      • @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                        – HolyBlackCat
                        8 часов назад












                      • @Croessmah Расска́жите подробнее?

                        – HolyBlackCat
                        8 часов назад

















                      • а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                        – tim bars
                        9 часов назад












                      • это всё весьма и весьма сомнительно.

                        – Croessmah
                        9 часов назад











                      • @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                        – HolyBlackCat
                        8 часов назад












                      • @Croessmah Расска́жите подробнее?

                        – HolyBlackCat
                        8 часов назад
















                      а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                      – tim bars
                      9 часов назад






                      а для чего тогда стоит использовать string_view? И чем это лучше чем константная ссылка, с ней то по идее будет вызван только copy конструктор

                      – tim bars
                      9 часов назад














                      это всё весьма и весьма сомнительно.

                      – Croessmah
                      9 часов назад





                      это всё весьма и весьма сомнительно.

                      – Croessmah
                      9 часов назад













                      @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                      – HolyBlackCat
                      8 часов назад






                      @timbars "чем это лучше" Тем, что при таком варианте мы можем в некоторых случаях избежать копирования - когда передаем в функцию временный объект (rvalue). string_view, имхо, нужен для функций, анализирующих строки или сегменты строк (при парсинге и т. п.). Как универсальный "параметр-строка" он не особо прижился, имхо, потому что часто требудется, чтобы параметр был null-terminated, чего string_view не дает.

                      – HolyBlackCat
                      8 часов назад














                      @Croessmah Расска́жите подробнее?

                      – HolyBlackCat
                      8 часов назад





                      @Croessmah Расска́жите подробнее?

                      – HolyBlackCat
                      8 часов назад











                      1















                      1. Если строка будет "просто скопирована", то вам следует реализовывать либо "ленивый" вариант семантики перемещения (передавать std::string по значению и затем делать из него перемещение), либо "полный" вариант семантики перемещения (писать две перегруженных функции: для const std::string & и для std::string &&), либо, возможно, реализовать forwarding (писать шаблонную функцию, принимающую универсальную сслыку и делающую std::forward в вашу копию).



                        См. https://ru.stackoverflow.com/a/822789/182825



                      2. std::string_view уместен везде, где вы будете просто анализировать строку, т.е. он является заменителем const std:string & в ситуациях, когда копирование не будет делаться.






                      поделиться|улучшить этот ответ



























                        1















                        1. Если строка будет "просто скопирована", то вам следует реализовывать либо "ленивый" вариант семантики перемещения (передавать std::string по значению и затем делать из него перемещение), либо "полный" вариант семантики перемещения (писать две перегруженных функции: для const std::string & и для std::string &&), либо, возможно, реализовать forwarding (писать шаблонную функцию, принимающую универсальную сслыку и делающую std::forward в вашу копию).



                          См. https://ru.stackoverflow.com/a/822789/182825



                        2. std::string_view уместен везде, где вы будете просто анализировать строку, т.е. он является заменителем const std:string & в ситуациях, когда копирование не будет делаться.






                        поделиться|улучшить этот ответ

























                          1












                          1








                          1








                          1. Если строка будет "просто скопирована", то вам следует реализовывать либо "ленивый" вариант семантики перемещения (передавать std::string по значению и затем делать из него перемещение), либо "полный" вариант семантики перемещения (писать две перегруженных функции: для const std::string & и для std::string &&), либо, возможно, реализовать forwarding (писать шаблонную функцию, принимающую универсальную сслыку и делающую std::forward в вашу копию).



                            См. https://ru.stackoverflow.com/a/822789/182825



                          2. std::string_view уместен везде, где вы будете просто анализировать строку, т.е. он является заменителем const std:string & в ситуациях, когда копирование не будет делаться.






                          поделиться|улучшить этот ответ














                          1. Если строка будет "просто скопирована", то вам следует реализовывать либо "ленивый" вариант семантики перемещения (передавать std::string по значению и затем делать из него перемещение), либо "полный" вариант семантики перемещения (писать две перегруженных функции: для const std::string & и для std::string &&), либо, возможно, реализовать forwarding (писать шаблонную функцию, принимающую универсальную сслыку и делающую std::forward в вашу копию).



                            См. https://ru.stackoverflow.com/a/822789/182825



                          2. std::string_view уместен везде, где вы будете просто анализировать строку, т.е. он является заменителем const std:string & в ситуациях, когда копирование не будет делаться.







                          поделиться|улучшить этот ответ












                          поделиться|улучшить этот ответ



                          поделиться|улучшить этот ответ










                          ответ дан 6 часов назад









                          AnTAnT

                          50.2k33895




                          50.2k33895



























                              черновик сохранён

                              черновик удалён
















































                              Спасибо за ваш ответ на Stack Overflow на русском!


                              • Пожалуйста, убедитесь, что публикуемое сообщение отвечает на поставленный вопрос. Предоставьте как можно больше деталей, расскажите про проведенное исследование!

                              Но избегайте


                              • Просьб помощи, уточнений или ответов на темы не относящиеся к вопросу.

                              • Ответов основанных на мнениях; приводите аргументы основанные только на реальном опыте.

                              Также, обратите внимание на заметку в справочном центре о том, как писать ответы.




                              черновик сохранён


                              черновик удалён














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fru.stackoverflow.com%2fquestions%2f954084%2fstdstring-vs-const-stdstring-vs-stdstring-view%23new-answer', 'question_page');

                              );

                              Отправить без регистрации















                              Необходима, но никому не показывается





















































                              Необходима, но никому не показывается














                              Необходима, но никому не показывается












                              Необходима, но никому не показывается







                              Необходима, но никому не показывается

































                              Необходима, но никому не показывается














                              Необходима, но никому не показывается












                              Необходима, но никому не показывается







                              Необходима, но никому не показывается







                              Popular posts from this blog

                              Word for a person who has no opinion about whether god existsWord for having a definite opinion while simultaneously withholding judgment?What's the opposite of “newcomer? Is ”veteran" OK?What do you call an “atheist” who might believe in an afterlife?What's a word for someone who wants to voice opinions but not have them challenged?Word for someone who dismisses contrary opinions as irrational?Somone who thinks they are overly special/out of the ordinaryIs there a word, phrase or idiom for “a person who is incapable of thinking about the future”?The belief that a god is human-likeA word for a non-famous person/thing you have heard a lot aboutAdjective for a person who enjoys taking care of their appearance

                              What was this official D&D 3.5e Lovecraft-flavored rulebook?What was this set of RPG tools called?As a first-time DM should I let my players play complex character classes and roles?Nymph's Kiss and the RelationshipWhat was the name of this Cleric Prestige Class that shapes metal with its bare hands?Are the 3.5e Dragonlance books third party or official works?What's up with the domain Vile Darkness?What was this 80s book about RPGs?What was the name of this Werewolf band?What book had Rituals to “upgrade” animal companions to keep them viable at higher levels?What was this RPG that had rules for player-owned businesses?

                              2017 IndyCar Series Contents Series news Teams and drivers Schedule Season summary Footnotes References External links Navigation menu"INDYCAR: Initial 2018 bodywork concepts unveiled"the original"IndyCar confirms switch to Performance Friction brakes in 2017""AJ Foyt Racing will switch to Chevy"the original"Carlos Munoz, Conor Daly will drive for AJ Foyt Racing""Zach Veach's Indy 500 Debut Confirmed with Foyt""No mass exodus from Honda after Ganassi switch""Ex-F1 driver Sato joins Andretti Autosport for 2017 IndyCar season""IndyCar's Ryan Hunter-Reay, sponsor DHL paired through 2020""hhgregg and Andretti Autosport announce partnership for key races in 2016""INDYCAR: Rossi re-signs with Andretti"the original"McLaren Formula 1 - Fernando Alonso to race at Indy 500 with McLaren, Honda and Andretti Autosport""Shank will finally take part in Indy 500 with Harvey, Andretti | MotorSportsTalk""Andretti adds Jack Harvey to Indy 500 field""Ganassi switches to Honda power for 2017""INDYCAR: Chilton returns to Ganassi"the original"IndyCar silly season: Who's going where in 2017?""INDYCAR: Kanaan, NTT Data return to Ganassi"the original"Kimball to remain at Ganassi for 2017""Coyne confirms Bourdais for 2017 IndyCar season""Davison to sub for Bourdais in Indy 500"the original"Gutierrez confirmed for Detroit IndyCar debut""Gutierrez returns with Coyne for rest of 2017 season""Vautier to drive for Coyne at Texas"the original"INDYCAR: Coyne confirms Jones for 2017"the original"Pippa Mann returns to Coyne for Indy 500""Karam, Dreyer & Reinbold teaming up again for Indianapolis 500""Pigot to return to Ed Carpenter Racing""Hildebrand confirmed as full-time Ed Carpenter driver""Veach to replace injured Hildebrand at Barber"the originalNew Team Harding Racing Enters Chaves for 101st Indianapolis 500"Juncos Racing Announces Entry in 101st Running of the Indianapolis 500 :: Juncos Racing""Juncos confirms Pigot for Indy 500""Saavedra confirmed in Juncos' second 500 entry"the original"Lazier confirms Indy 500 run after son's USF2000 debut"the original"Claman DeMelo to race for RLLR at Sonoma"the original"Rahal signs Servia and ace engineer for 2017""IndyCar: Aleshin returns with Schmidt"the original"Aleshin replaced by Saavedra for Toronto""Jack Harvey will pilot SPM No. 7 car at Watkins Glen, Sonoma""Jay Howard confirmed in Tony Stewart's supported SPM Indy entry""INDYCAR: Newgarden to wave the flag at Penske"the original"Pagenaud opts for No. 1 in 2017"the original"Penske confirms Newgarden for 2017""Montoya to stay with Team Penske in 2017""Target leaving IndyCar after 27 seasons with Chip Ganassi""Cavin: IndyCar could see complete driver/team shakeup in 2017""End of the road for KV Racing?""KV Racing confirms closure, equipment sold to Juncos""Juncos confirms IndyCar Series entry"the original"Juncos readies IndyCar program, aims for '17 500"the original"Harding Racing to add Texas, Pocono to schedule"the original"Sato signs with Andretti Autosport for 2017""INDYCAR: Aleshin in Doubt at SPM"the original"Long Beach notebook: JR Hildebrand breaks hand""Hildebrand cleared to return at Phoenix"the original"Bourdais to undergo surgery on multiple fractures""Aleshin loses Schmidt Peterson IndyCar ride""Saavedra in at SPM for Pocono, Gateway"the original"Bourdais to make return at Gateway"the original"The IndyCar Grand Prix no longer is sponsored by Angie's List""2017 IndyCar Series rulebook""2017 Verizon IndyCar Series Official Rulebook"Official websiteeeeee