С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/40: Рейтинг темы: голосов - 40, средняя оценка - 4.60
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12

Передача строки в качестве параметра

07.06.2019, 16:31. Показов 8036. Ответов 66
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>
 
void test(const std::string& str)
{
    std::cout << str;
}
 
int main()
{
  test("Hello my dear friend!\n");
}
Что происходит?
Создаётся временный объект const std::string, конструктор которого принимает (и копирует в себя) const char*, вызывается функция test, затем объект уничтожается. Много лишних действий.

Можно ли сделать так, чтобы в EXE-шнике изначально хранился объект std::string, а не создавался перед вызовом функции?

p.s. В идеале – C++11, но если вариантов нет, рассмотрю что есть.

p.p.s. Интересен также вариант без создания промежуточных констант, если такое возможно, потому что, понятное, дело, можно сделать const std::string text = "Hello my dear friend!\n"; и подставлять её, но это неинтересно. Да и всё равно объект создаётся динамически.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.06.2019, 16:31
Ответы с готовыми решениями:

Передача функции в качестве параметра
Все привет. Помогите в решении следующей проблемы: есть класс XXX, один из методов которого принимает в качестве параметра указатель на...

Передача класса в качестве параметра
Здраствуйте, вообщем есть код class Main: public ExampleApplication { public: void createScene(void) { /* создаем...

Передача пути к файлу в качестве параметра через консоль
Доброго времени суток. Как в самой программе передать в качестве параметра путь к файлу? Понятное дело, что в консоли: путь до файла и...

66
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 16:34
Цитата Сообщение от Jin X Посмотреть сообщение
Можно ли сделать так, чтобы в EXE-шнике изначально хранился объект std::string, а не создавался перед вызовом функции?
Только объявить static const std::string'
В 17-ом стандарте появилась std::string_view - void test(const std::string_view& str)

Добавлено через 15 секунд
С ней этих проблем нет
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 16:41  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Только объявить static const std::string
Всё равно в EXE-шнике будет храниться ASCIIZ-строка, которая преобразуется в string.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
void test(const std::string_view& str)
Проблема в том, что string нужен для того, чтобы хранить строки, которые могут быть удалены. Иначе можно было бы вообще const char* использовать.

Например:
C++
1
2
3
4
5
void something(std::function<void()> func, const char* str)
{
  func();
  std::cout << str;  // но проблема в том, что func может удалить строку из памяти, и указатель str станет невалидным.
}
Такая же ерунда и со string_view, как я понимаю, может быть.

Добавлено через 31 секунду
Может, через constexpr как-то можно? Но constexpr std::string сделать не получится...
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 16:43
Цитата Сообщение от Jin X Посмотреть сообщение
Такая же ерунда и со string_view, как я понимаю, может быть.
Нет, не может. Для константных строк она всегда создаётся в compile-time

Добавлено через 43 секунды
Цитата Сообщение от Jin X Посмотреть сообщение
Всё равно в EXE-шнике будет храниться ASCIIZ-строка, которая преобразуется в string.
Ну да, она в любом случае должна там храниться
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 16:45  [ТС]
Т.е. если передаём const char*, то строка копируется, и пусть исходная удаляется, фиг с ней.
А если зашитую в код как константу, то никуда она не денется, можно и ссылку передать на оригинал.

Добавлено через 41 секунду
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Для константных строк она всегда создаётся в compile-time
Для константных, может, и создаётся, а если там будет переменная char* ?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 16:45
Цитата Сообщение от Jin X Посмотреть сообщение
Проблема в том, что string нужен для того, чтобы хранить строки, которые могут быть удалены. Иначе можно было бы вообще const char* использовать.
В смысле, кем они могут быть удалены?
Можешь const char * поставить, и сделать test(std::string("1111").c_str());
Пока функция test не завершится, строка не будет удалена.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 16:46  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну да, она в любом случае должна там храниться
А почему сразу готовый объект не может храниться?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 16:48
Цитата Сообщение от Jin X Посмотреть сообщение
Для константных, может, и создаётся, а если там будет переменная char* ?
А какие там есть варианты?

Добавлено через 1 минуту
Цитата Сообщение от Jin X Посмотреть сообщение
А почему сразу готовый объект не может храниться?
Он и хранится. С тех пор, как появился constexpr, а может и раньше.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 16:50  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В смысле, кем они могут быть удалены?
Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstring>
#include <functional>
 
void call(std::function<void()> func, const char* str)
{
  func();
  std::cout << str;  // но проблема в том, что func может удалить строку из памяти, и указатель str станет невалидным.
}
 
int main()
{
  char* s = new char[20];
  strcpy(s, "Hello World!");
  call([&s](){ strcpy(s, "Good bye!"); }, s);
  delete[] s;
 
  return 0;
}
Выдаст Good bye!, а не Hello World!
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 16:58
На самом деле, скорее всего для const std::string & и константы компилятор у тебя просто подставит эту константу в выражение

Добавлено через 1 минуту
Цитата Сообщение от Jin X Посмотреть сообщение
Выдаст Good bye!, а не Hello World!
Всё правильно - ты передаёшь адрес и изменяешь содержимое массива. Точно также ты и std::string можешь изменить в этой функции

Добавлено через 4 минуты
А, ну да, ты имел ввиду, что передашь c_str(), а потом изменишь std::string.
Ну, так делать плохо.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 17:00  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Точно также ты и std::string можешь изменить в этой функции
Я могу объявить её вот так: void call(std::function<void()> func, const std::string str). Тогда мне будет по барабану на эти изменения.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 17:03
Цитата Сообщение от Jin X Посмотреть сообщение
Я могу объявить её вот так: void call(std::function<void()> func, const std::string str). Тогда мне будет по барабану на эти изменения.
Там точно не ссылка на std::string?
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 17:04  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну, так делать плохо.
ИМХО, плохо делать так не в лямбде, а в вызывающей функции. Т.е. когда изменение исходной передаваемой строки влечёт к изменению работы функции.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 17:07
Цитата Сообщение от Jin X Посмотреть сообщение
ИМХО, плохо делать так не в лямбде, а в вызывающей функции. Т.е. когда изменение исходной передаваемой строки влечёт к изменению работы функции.
Думаю, так плохо делать везде - передавать константную ссылку или указатель и изменять его втихую.
Но, способов писать плохие программы очень много и пытаться строить от них всех защиту - дело неблагодарное
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 17:10  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Там точно не ссылка на std::string?
Ну если будет ссылка, я же могу изменить исходную строку в func, и call выведет не то, что ей передали изначально. А если НЕ ссылка, то то, что передали.

Добавлено через 1 минуту
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Думаю, так плохо делать везде - передавать константную ссылку или указатель и изменять его втихую.
Если я пишу функцию, которой могут пользоваться другие, то проконтролировать изменения внутри вызываемой функции func я не могу, а внутри call – могу. В этом и суть.

Добавлено через 1 минуту
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Он и хранится. С тех пор, как появился constexpr, а может и раньше.
Так, я же не могу использовать constexpr вместе с std::string. Как быть?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 17:19
Цитата Сообщение от Jin X Посмотреть сообщение
Если я пишу функцию, которой могут пользоваться другие, то проконтролировать изменения внутри вызываемой функции func я не могу, а внутри call – могу. В этом и суть.
Думаю, лучше пусть это будут проблемы тех, кто пользуется. В данном случае ты жертвуешь производительностью, ради защиты от идиотов. причём пострадают все.

Добавлено через 5 минут
Цитата Сообщение от Jin X Посмотреть сообщение
Так, я же не могу использовать constexpr вместе с std::string. Как быть?
Не, здесь я имел ввиду constexpr-методы. Но, скорее всего, компилятор пока не умеет динамически выделять память в compile-time, поэтому std::string так не построить

Добавлено через 1 минуту
Само-собой он оптимизирует вызов - например, если в твоей функции будет вызываться только c_str() для параметра, то, думаю, даже объект не будет создаваться
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
07.06.2019, 18:02
Цитата Сообщение от Jin X Посмотреть сообщение
Если я пишу функцию, которой могут пользоваться другие, то
забей и не парься.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
07.06.2019, 18:08
Цитата Сообщение от Jin X Посмотреть сообщение
Проблема в том, что string нужен для того, чтобы хранить строки, которые могут быть удалены.
Как-то не стыкуется "могут быть удалены" и "чтобы в EXE-шнике изначально хранился объект".

Цитата Сообщение от Jin X Посмотреть сообщение
Для константных, может, и создаётся, а если там будет переменная char* ?
А так?
C++
1
2
3
4
5
6
7
8
9
10
void test(char * str)
{
    std::cout << str;
}
 
int main()
{
  static char str[] = "Hello my dear friend!\n";
  test(str);
}
В С++ есть два варианта инициализации объектов со static storage duration - статическая и динамическая. std::string "зашитый в exe" никак не может быть статически инициализирован, т.к. в нем используется динамическая память.

Если же речь о константе с automatic storage duration, то это такой же объект на стеке. Он живет в области видимости функции и будет создаваться каждый раз, когда поток управления дойдет до этого места.

Строковый литерал константен и имеет static storage duration, поэтому его как раз можно "зашить в exe".


Лучше опишите конкретно ту задачу, где вам это понадобилось.
0
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6809 / 2049 / 238
Регистрация: 14.12.2014
Сообщений: 4,300
Записей в блоге: 12
07.06.2019, 20:37  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Как-то не стыкуется "могут быть удалены" и "чтобы в EXE-шнике изначально хранился объект".
Всё стыкуется. Передавать можно разные данные. И константный объект, зашитый в EXE-шнике и ссылку на объект, который может быть удалён.

Цитата Сообщение от DrOffset Посмотреть сообщение
А так?
Что так? Не очень понял, к чему этот пример.

Цитата Сообщение от DrOffset Посмотреть сообщение
std::string "зашитый в exe" никак не может быть статически инициализирован, т.к. в нем используется динамическая память.
Хм. Звучит логично

Цитата Сообщение от DrOffset Посмотреть сообщение
Лучше опишите конкретно ту задачу, где вам это понадобилось.
Intel C++ Compiler выдаёт ремарки. В одной из них написал: value copied to temporary, reference to temporary used. И я подумал, что вероятно, можно сделать так, чтобы не было временных объектов. Он как раз написал при вызове с аргументом "строка" функции, которая принимает const std::string&. А ещё вот на такую строку тоже написал: std::this_thread::sleep_for(std::chrono::milliseconds(1000)); (причём, ткнул на число 1000).
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
07.06.2019, 20:55
Цитата Сообщение от Jin X Посмотреть сообщение
Intel C++ Compiler выдаёт ремарки. В одной из них написал: value copied to temporary, reference to temporary used. И я подумал, что вероятно, можно сделать так, чтобы не было временных объектов. Он как раз написал при вызове с аргументом "строка" функции, которая принимает const std::string&. А ещё вот на такую строку тоже написал: std::this_thread::sleep_for(std::chrono: :milliseconds(1000)); (причём, ткнул на число 1000).
Что-то здесь неправильно. Покажи код.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.06.2019, 20:55
Помогаю со студенческими работами здесь

Передача строки в качестве аргумента потоку
Создаю массив handle'ов HANDLE threads; Есть массив, состоящий из 5 символов &quot;ABCDE&quot; char symb; Создаю потоки...

Передача функции в качестве параметра
Как передать функцию с параметрами в transform? Т.е., например, мне надо из каждого числа вектора вычесть число k с помощью transform'а,...

Передача файла в качестве параметра
Как, в качестве параметра, передать функции файл и структуру??? Добавлено через 1 час 1 минуту Разве никто не знает???

Передача функции в качестве параметра
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; double f(double x) { return (2*x*x)-(exp(x)); double...

Передача CString в качестве параметра функции
Добрый всем вечер! Мучает один вопрос, на который не могу найти ответ. Как наилучшим образом передавать объект класса CString в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru