首页 > 解决方案 > 我可以安全地从 c++ 中的 std::stringstream 中获取 c_str 吗?

问题描述

我正在使用一个 C 函数,该函数接受一个字符串(即指向一个以空字符结尾的 char 数组的指针)并在内部对其进行处理。但是,它不会在函数返回后保留对字符串的引用。

我想向它传递一些格式化的输入,所以我使用的是std::stringstream. 为了让我的代码更干净——而且因为这种模式在整个代码库中重复出现,我想简单地通过ss.str().c_str().

对我来说,这似乎很可怕,因为我正在临时调用一个方法ss.str(),但我认为这没关系,因为可以延长生命周期。即,标准说:

在函数调用 (5.2.2) 中对引用参数的临时绑定一直持续到包含调用的完整表达式完成 [...] 在所有这些情况下,在初始化引用的表达式的评估期间创建的临时对象,除了引用绑定到的临时对象外,它们在创建它们的完整表达式的末尾被销毁,并且以它们构造完成的相反顺序被销毁。

(强调我的)

因此,我希望我的价值观会一直持续到 C API 调用结束。我弄错了吗?这样做安全吗?从概念上讲,我的代码如下所示:

void g(int x, int y) {
    std::stringstream ss;
    ss << "(" << x << ", " << y << ")";
    puts(ss.str().c_str());
}

标签: c++referencepass-by-referencelifetime

解决方案


是的,这很好,并且ss.str().c_str()在使用 C 风格的 API 时经常出现。

通俗地说,从函数调用中std::string返回的匿名临时ss.str()对象仍然存在。puts()这意味着const char*返回的指针c_str()在 的持续时间内保持有效puts()

不能做的是:

const char* ub = ss.str().c_str();
puts(ub);

因为指针ub悬空。


推荐阅读