Создание константной строки по условию
Есть код следующего вида:
std::string str;
if (x > 0) str = "positive";
else if (x < 0) str = "negative";
else str = "zero";
Хочется переписать код так, чтобы str было бы константой.
Как это сделать "красиво"? Некрасиво - создать функцию, "вычисляющую" эту строку, и вернуть её:
const std::string str = Foo ();
Или вообще создать прямо тут на месте лямбду... Но так не хочется :) .
Ответы (5 шт):
Ну если без функции, то можно на месте сначала задать аргументы конструктора, а затем только создавать строку с const квалификатором.
char const * psz_value{};
::std::size_t value_length{}
if (x < 0)
{
constexpr auto const & sz_value{"negative"}
psz_value = sz_value;
value_length = ::std::size(sz_value) - 1;
}
else if (0 == x)
{
constexpr auto const & sz_value{"zero"}
psz_value = sz_value;
value_length = ::std::size(sz_value) - 1;
}
else
{
constexpr auto const & sz_value{"positive"}
psz_value = sz_value;
value_length = ::std::size(sz_value) - 1;
}
::std::string const str{psz_value, value_length};
Но я бы вообще засунул эти строки в таблицу вместо пересоздания каждый раз.
const std::string str = x > 0 ? "positive" : x < 0 ? "negative" : "zero";
Так годится?
Если это локальная переменная, то можно объявить дополнительную константную ссылку :
std::string str_pri;
std::string const & str = str_pri ;
if (x > 0) str_pri = "positive";
else if (x < 0) str_pri = "negative";
else str_pri = "zero";
А если глобальная переменная, то можно рабочую спрятанную переменную хранить в отдельном исходнике, а в открытый доступ передавать только константную ссылку.
public.hpp :
extern std::string const & str_pub ;
private.cpp :
static std::string str_pri;
std::string const & str_pub = str_pri ;
if (x > 0) str_pri = "positive";
else if (x < 0) str_pri = "negative";
else str_pri = "zero";
const int i = x < 0 ? -1 : x == 0 ? x : 1;
const string p[3] = { "negative", "zero", "positive" };
const string str = p[i + 1];
В общем случае это решается лямбдой:
const std::string str = [&]{
std::string str;
// str = ...
return str;
}();
Но для такого простого случая я бы взял предложенный Harry ? :.