Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/40: Рейтинг темы: голосов - 40, средняя оценка - 4.60
Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6818 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,332
Записей в блоге: 13

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

07.06.2019, 16:31. Показов 8672. Ответов 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
08.06.2019, 14:13
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DrOffset Посмотреть сообщение
В моем коде - это так, но GCC 9.1 все равно делает runtime и это скорее всего баг.
Извини, я возможно, забыл, но в каком коде ты передавал туда constexpr-выражение, и каким образом?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
09.06.2019, 03:24
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
но в каком коде ты передавал туда constexpr-выражение, и каким образом?
В таком же, в каком туда его ты передавал.

Короче, они говорят - это не баг. Регресс оптимизатора в 9.1 - да.
Говорят, что constexpr контекст не существует из-за того, что переменная, которая инициализируется результатом Test(), сама не constexpr. По этому же получается, что отдельные вызовы в main тоже не constexpr, предвычисление в этом случае заслуга оптимизатора. Библиотечная реализация использует интринсики, которые помогают оптимизатору, но constexpr все равно не используется по причинам озвученным выше. Это хорошо видно, если выкрутить оптимизацию в ноль. Обе функции работают в runtime: https://godbolt.org/z/D1kmZN

Также предлагают ждать С++20, где функция Test может быть consteval, тогда она будет вести себя как я предполагал изначально.

Корректный пример с точки зрения constexpr контекста выглядит так: https://godbolt.org/z/VxjgSI
Флаг оптимизации специально выкручен в ноль, чтобы показать, что оптимизация на результат не влияет.

Мораль1: чтобы функция была constexpr, на всем этапе вычислений не должно быть не-constexpr сущностей, иначе работать будет в рантайме, где уже возможно поможет оптимизатор и сгладит различия, но не обязан.

Мораль2: со сказанным мной выше в этой теме противоречий мало (за исключением предположений о баге). Все так же остаются верными:
* Пишем все в constexpr контексте и получаем constexpr результат.
* Код компилятор компилирует одинаково.
* Проблемы в пользовательской Length нет никакой.

Собственно теперь все понятно, кроме одного, какая собственно позиция у тебя? Ты с чем сейчас не согласен? По твоим ответам вообще не ясно, к чему мы пришли.

Вот тебе реализация с вырезанием имени файла из __FILE__, вдруг мне станет понятнее чего ты вообще добиваешься. Реально, понять тебя крайне тяжело, без обид.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <cstdio>
 
constexpr size_t length(char const * f)
{
    size_t l = 0;
    while(f[l++]);
    return l;
}
 
constexpr size_t filename(char const * f, char D)
{
    char const * p = f;
    char const * d = p;
    while(*p) if(*p++ == D) d = p;
    return d - f;
}
 
template <size_t L, typename S, size_t P, char ...Chars>
struct FileNameBase 
    : FileNameBase<L, S, P + 1, Chars..., S{}.a[P]>
{ };
template <size_t L, typename S, char ...Chars>
struct FileNameBase<L, S, L, Chars...>
{
    static constexpr char value[] = { Chars..., 0 };
};
template <size_t L, typename S, char ...Chars>
constexpr char FileNameBase<L, S, L, Chars...>::value[];
 
template <typename S, char D>
struct FileName
    : FileNameBase<length(S{}.a), S, filename(S{}.a, D)>
{ };
 
int main()
{
    struct P { char const * a = __FILE__; };
    
    printf("%s", FileName<P, '/'>::value);
}
https://godbolt.org/z/jxSFSf
С++14 и выше. Написано этим утром за 5 минут, на случай, если ты все-таки решил бы создать тему. Как видно, от полного пути осталось только имя файла. Самого полного пути нигде в секции rodata нет, оптимизация выкручена в ноль, все манипуляции со строкой произведены на этапе компиляции, как ты и заказывал. Оптимизациями кода не занимался. Можно сделать лучше, но мне лень. Может быть кому-то пригодится как отправная точка.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
09.06.2019, 10:56
Цитата Сообщение от DrOffset Посмотреть сообщение
Собственно теперь все понятно, кроме одного, какая собственно позиция у тебя? Ты с чем сейчас не согласен? По твоим ответам вообще не ясно, к чему мы пришли.
Ну, я изначально был не согласен с одним - какого хрена их функция выполняется в compile-time, а моя в runtime, при прочих равных условиях. Если бы обе выполнялись в рантайме, вопросов бы не возникло.

Добавлено через 7 минут
Ну и из предыстории - я делал форматирование даты-времени, типа strftime.
Там нужно выделять буфер под результат. Я подумал, что так как почти всегда строка форматирования это константа, неплохо было бы этот размер вычислять в compile-time, когда это возможно. Не получилось.
Сделал функцию попроще, length - то же самое. Но (!) аналогичная функция char_traits::length отрабатывает нормально

Добавлено через 6 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот тебе реализация с вырезанием имени файла из __FILE__, вдруг мне станет понятнее чего ты вообще добиваешься. Реально, понять тебя крайне тяжело, без обид.
К
Да какие, нафиг, обиды. Мне просто надо чтоб мой код адекватно работал.
Вот моя реализация
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#define TS_FILE_LINE FileLine(&__FILE__[std::integral_constant<size_t, GetFileNameOffset(__FILE__)>::value], __LINE__)
inline
constexpr size_t GetFileNameOffset(const char *file) noexcept
{
    for (auto *p = file + std::char_traits<char>::length(file) - 1; p > file; --p)
        if (IsOneOf(*p, '\\', '/'))
            return p - file;
        
    return 0;
}
 
struct FileLine
{
    FileLine() = default;
 
    constexpr FileLine(const std::string_view &__file__, const int __line__) noexcept
    : m_file(__file__)
    , m_line(__line__)
    {
    }
 
    void Format(TFormatOutput &out) const
    {
        FormatVals<CommaSpace>(out, m_file, m_line);
    }
 
    const std::string_view m_file{""};
    const int m_line = 0;
};
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
09.06.2019, 16:02
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
какого хрена их функция выполняется в compile-time, а моя в runtime, при прочих равных условиях.
Ну вот что мне ответили в багзилле:
The reason why you don't get it all compile time evaluated is that if it is not is_constant_evaluated, the std length will then use a builtin function instead of evaluating it a character by character, but that makes it fail when the compiler tries to evaluate it as a non-manifestly constant-evaluated constant expression. And your own length on the other side wants to be evaluated only as a constant expression, otherwise it isn't optimized well.
Я примерно об этом же и говорил.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Мне просто надо чтоб мой код адекватно работал.
Можешь привести полный пример, чтобы я мог его запустить?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
09.06.2019, 16:44
Цитата Сообщение от DrOffset Посмотреть сообщение
Можешь привести полный пример, чтобы я мог его запустить?
Полный пример чего?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
09.06.2019, 20:25
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Полный пример чего?
Ну того кода, который должен адекватно работать.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
09.06.2019, 21:18
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну того кода, который должен адекватно работать.
Там, собственно, неадекватность в том и состояла, что я рассчитывал на compile-time (посмотрев на char_traits::length), а оно отработало в рантайме.
Печально, но, похоже, для строк constexpr-функции пока бесполезны.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.06.2019, 21:18

Передача строки в качестве аргумента потоку
Создаю массив 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 в...


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

Или воспользуйтесь поиском по форуму:
67
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru