Время жизни переменной C++ - требуется временное решение для временного возврата
У меня есть объект C++ (boost::format
) который имеет str()
функция, которая возвращает std::string
,
Поэтому, когда мне нужна отформатированная строка C, мне нужно написать что-то вроде:
(boost::format("%1% %2%") % "1" % "2").str().c_str()
Я нахожу это довольно многословным, и мне это очень нужно. Я думал о создании производного класса, который имеет operator char*
и будет работать так (Ch = char или wchar_t):
operator Ch const* () const
{
return str().c_str();
}
Но, конечно, строка возвращается str()
освобождается, когда функция возвращается, и верная строка C не возвращается.
Есть ли какое-нибудь решение?
Обходной путь должен создать строку, которая существует до тех пор, пока вызов окружающей функции:
lib_function((boost::format("%1% %2%") % "1" % "2").str().c_str());
// can be deallocated here
3 ответа
Наиболее очевидным решением является определение типа, который содержитstd::string
и преобразует неявно в char const*
, Что-то вроде:
class ToPlainC
{
std::string myValue
public:
ToPlainC( boost::format const& fmt )
: myValue( fmt.str() )
{
}
operator char const*() const
{
return myValue.c_str();
}
};
который может быть использован:
lib_function( ToPlainC( boost::format( "%1% %2%" ) % "1" % "2" ) );
Такие неявные преобразования обычно не являются хорошей идеей, но если вы хорошо документируете класс, что его следует использовать только для этого конкретного сценария, я думаю, что это будет приемлемо.
РЕДАКТИРОВАТЬ:
Мне приходит в голову, что для поощрения использования только этого класса как временного, в этом конкретном сценарии вы можете назвать его, используя соглашения об именах, которые вы обычно используете для функций, а не те, которые вы используете для классов; тогда у пользователя будет впечатление, что он использует функцию, и он будет торчать, как больной большой палец, если он будет использовать ее в противном случае.
Вернуть std::string в стеке. Это дополнительная копия, поэтому плохая идея, если производительность важна, но она будет работать, чтобы устранить большую часть избыточной типизации.
Вы можете определить структуру как показано ниже:
struct my_str
{
const std::string &tmp;
my_str(const boost::format &tmp) : tmp( tmp.str() ) {}
operator const char *() const { return tmp.c_str(); }
};
И вы можете назвать это как
lib_function ( my_str(boost::format("%1% %2%") % "1" % "2") );
Если вы волнуетесь, ссылка будет болтаться, прочитайте эту статью.