Asm/C++/Delphi/Py/PHP/VBA
 Аватар для Jin X
6818 / 2056 / 239
Регистрация: 14.12.2014
Сообщений: 4,332
Записей в блоге: 13

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

07.06.2019, 16:31. Показов 8707. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru