0

我有一个 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
4

3 回答 3

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

这种隐式转换通常不是一个好主意,但如果你很好地记录了这个类,它应该用于这个特定的场景,我认为它是可以接受的。

编辑:

我突然想到,为了鼓励仅将此类用作临时类,在此特定情况下,您可以使用通常用于函数的命名约定来命名它,而不是用于类的命名约定;然后,用户会觉得他正在使用一个功能,如果他不使用它,它会像拇指酸痛一样伸出来。

于 2014-04-29T13:43:31.177 回答
1

在堆栈上返回一个 std::string。这是一个额外的副本,所以如果性能很重要,那不是一个好主意,但它可以消除大部分多余的输入。

于 2014-04-29T12:55:44.943 回答
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") );

如果您担心引用会悬空,请阅读本文

于 2014-04-29T13:40:34.410 回答