C ++变量生命周期 - 需要变通方法才能返回临时变量

时间:2014-04-29 12:49:56

标签: c++ cstring stdstring object-lifetime boost-format

我有一个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 个答案:

答案 0 :(得分:4)

最明显的解决方案是定义一个包含的类型 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" ) );

这种隐含的转换通常不是一个好主意,但如果 你很好地记录了这个类,它应该只用 这个特殊情况,我认为这是可以接受的。

编辑:

我觉得鼓励只使用这个课程 一个临时的,在这个特殊情况下,你可以命名它 使用通常用于函数的命名约定,和 不是那些用于上课的人;然后用户将拥有 他正在使用一个功能的印象,它会坚持下去 如果他使用它,就像一个酸痛的拇指。

答案 1 :(得分:1)

在堆栈上返回一个std :: string。它是一个额外的副本,所以如果性能很重要,这是一个坏主意,但它可以消除大多数冗余打字。

答案 2 :(得分:1)

您可以定义如下所示的结构:

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") );

如果您担心引用会悬空,请阅读this文章。