Что лучше для static const char* или static const string для объявления статических переменных

Я разрабатываю кроссплатформенную библиотеку C++. Мне нужен лучший способ определения моих строковых констант, которые будут использоваться во всей программе. Какой из них лучше static const char * или static const std::string? Делает ли constexpr какое-либо из них лучше старого объявления?

static const char *str = "hello world";

vs

static const string str = "hello world";

Зачем мне это нужно: моей программе, возможно, придется инициализировать много статических переменных типа строковых литералов перед запуском приложения. И я не могу обойтись без статических переменных, потому что они используются во всем файле. Если мне нужно увеличить производительность, но сократить время инициализации статической переменной. В идеале я хотел бы, чтобы большинство вещей происходило во время компиляции, а не во время выполнения. какой из них будет лучшим выбором?


person venkat satish Katta    schedule 09.04.2019    source источник
comment
Какое использование статики здесь?   -  person Michael Chourdakis    schedule 09.04.2019
comment
лучше относительно чего? взаимодействие с c или с точки зрения предотвращения доступа за пределы? ;)   -  person 463035818_is_not_a_number    schedule 09.04.2019
comment
Это зависит от того, что вы делаете с этим.   -  person François Andrieux    schedule 09.04.2019
comment
Ключ в том, для чего вам нужна строка? Вам когда-нибудь понадобится получить длину? Вам нужно удобство string.length() или вы хотите использовать strlen(). В этом отношении вы можете #define STRCONST1 "My String Const" и так далее. Это зависит от того, как вы хотите использовать его в своем коде. Очевидно, что char * будет менее требовательным к компилятору и ресурсам, а #define и того меньше, но std::string предлагает много, ни один из них не требует небольших дополнительных затрат.   -  person David C. Rankin    schedule 09.04.2019
comment
Вы забыли string_view, который заменяет const char* в современном C++ (и который работает с constexpr, который вы должны использовать в этом случае).   -  person Matthieu Brucher    schedule 09.04.2019
comment
@DavidC.Rankin, мне не нужен strlen(). В большинстве случаев это используется для сравнения с другими строками или с этой переменной создается новый строковый объект.   -  person venkat satish Katta    schedule 09.04.2019
comment
@MatthieuBrucher, string_view — С++ 17, мы используем С++ 14   -  person venkat satish Katta    schedule 09.04.2019
comment
@ user463035818, чтобы избежать задержки запуска приложения, поскольку статические переменные инициализируются до запуска приложения.   -  person venkat satish Katta    schedule 09.04.2019
comment
Во втором вы назначаете char const* std::string. Почему бы не использовать новый синтаксис, который позволяет указать литерал std::string. static const string str = "hello world"s; (обратите внимание на последнюю букву s) en.cppreference.com/w /cpp/string/basic_string/operator%22%22s   -  person Martin York    schedule 09.04.2019


Ответы (5)


Обычно std::string хорошо, но в любом случае это зависит от того, что вы хотите сделать. Здесь нет абсолютной серебряной пули. std::string имеет конструктор и вызовет, например, new/malloc (когда нельзя применить оптимизацию SSO для небольших строк). Если это нежелательно по какой-либо причине, используйте const char*.

Это зависит также от того, где он будет использоваться. Если это заголовок окна HWND, например, и основное использование связано с функциями Windows API, он не будет отличаться, если вы все время используете метод c_str() std::string.

Все это к тому, что нет стопроцентного предпочтения того или иного.

Использование или нет static - это другое обсуждение.

person Michael Chourdakis    schedule 09.04.2019
comment
Моей программе, возможно, придется инициализировать много статических переменных типа строковых литералов перед запуском main. И я не могу обойтись без статических переменных, потому что они используются во всем файле. - person venkat satish Katta; 09.04.2019
comment
std::string has a constructor and will call new/malloc for example это утверждение неверно. Каждая современная реализация реализует SSO (оптимизация небольшой строки), которая хранится в стеке. - person KostasRim; 10.04.2019

Это будет зависеть от того, что вы делаете с этими переменными. Например, взгляните на это:

void do_stuff(std::string const&);

void stuff() {
    while(/* some condition */) {
        do_stuff(constant); // very hot loop
    }
}

Давайте рассмотрим два способа определения переменной constant:

constexpr auto constant = "value";          // (1)
auto const constant = std::string{"value"}; // (2)

В случае горячего цикла, если вы возьмете (1), он будет каждый раз создавать строку. Если строковое значение достаточно длинное, это может привести к выделению памяти. Тогда (2) лучше для этого случая.

С другой стороны, если вы реорганизуете свой код примерно так:

void do_stuff(std::string_view);

void stuff() {
    while(/* some condition */) {
        do_stuff(constant); // very hot loop
    }
}

Тогда ваша программа будет намного быстрее с (1), так как не будет происходить динамического распределения. Ваша программа будет ссылаться на исходные данные только для чтения вашей программы.

person Guillaume Racicot    schedule 09.04.2019

С современным C++ я бы использовал std::string_view.

Если вам нужно, чтобы это было std::string, то лучший вариант — определить его как статическую локальную переменную в функции, чтобы она лениво инициализировалась при первом запросе.

/* inline or not */
std::string const& get_that_string() {
    static std::string const str { "value" };
    return value;
}
person bobah    schedule 09.04.2019
comment
Этот подход может не масштабироваться, если есть большое количество статических переменных. функция записи для всего может быть чрезмерной - person venkat satish Katta; 09.04.2019
comment
используйте string_view, затем - person bobah; 09.04.2019

Если в вашей конкретной кодовой базе нет известных проблем с использованием std::string, я настоятельно рекомендую использовать std::string.

static std::string const str = "hello world";
person R Sahu    schedule 09.04.2019

В общем, вы должны предпочесть std::string char*. static не имеет к этому никакого отношения.

person Code-Apprentice    schedule 09.04.2019
comment
вопрос в объявлении статических переменных... так что static имеет к этому какое-то отношение;) - person 463035818_is_not_a_number; 09.04.2019