У меня есть объект 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
Наиболее очевидным решением является определение типа, который содержит
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") );
Если вы беспокоитесь, ссылка будет болтаться, прочитайте этот статья.