Время жизни переменной 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") );

Если вы волнуетесь, ссылка будет болтаться, прочитайте эту статью.

Другие вопросы по тегам