从函数返回字符串
returning a string from a function
我想写一个跨平台的函数(win32和linux),并返回datetime的字符串表示形式[hh:mm:ss dd-mm-yyyy]。
知道我只想以流方式将返回的字符串用作临时字符串,如下所示:
std::cout << DateTime() << std::endl;
我考虑使用以下原型编写一个函数
const char* DateTime();
如果返回字符数组,则必须在完成后将其删除。 但我只是想要一个临时的,我不想担心取消分配字符串。
所以我写了一个只返回一个 std::string 的函数:
#include <ctime>
#include <string>
#include <sstream>
std::string DateTime()
{
using namespace std;
stringstream ss;
string sValue;
time_t t = time(0);
struct tm * now = localtime(&t);
ss << now->tm_hour << ":";
ss << now->tm_min << ":";
ss << now->tm_sec << " ";
ss << now->tm_mday + 1 << " ";
ss << now->tm_mon + 1 << " ";
ss << now->tm_year + 1900;
sValue = ss.str();
return sValue;
}
我意识到我在日期时间中返回堆栈变量的副本。 这是低效的,因为我们在 DateTime 堆栈上创建字符串,填充它,然后返回一个副本并销毁堆栈上的副本。
c++11 移动语义革命是否为解决这种低效率做了什么 - 我可以改进一下吗?
lapin,你的代码很好C++11代码。 在 C++98/03 中,由于编译器优化,您的代码可能会高效,但不能保证这些优化。 在 C++11 中,这些相同的优化可能仍然会让你的回报免费,但以防万一,你的字符串将被移动而不是复制。
所以按价值返回无罪! :-)
小尼特:
最佳做法是在首次使用时声明值,而不是在块的顶部声明:
string sValue = ss.str();
return sValue;
甚至可能:
return ss.str();
但这只是一个小问题。 您的代码既精细又高效。
另一种方法是使其成为带有流插入器的函数对象,如下所示:
struct DateTime()
{
friend std::ostream& operator<<(std::ostream& os, DateTime)
{
time_t t = time(0);
struct tm * now = localtime(&t);
os << now->tm_hour << ":";
os << now->tm_min << ":";
os << now->tm_sec << " ";
os << now->tm_mday + 1 << " ";
os << now->tm_mon + 1 << " ";
os << now->tm_year + 1900;
return os;
}
// Could be converted to a static method,
// since DateTime has no internal state
std::string str() const
{
// the following 3 lines can be replaced by
// return boost::lexical_cast<std::string>(*this);
std::ostringstream ss;
ss << *this;
return ss.str();
}
operator std::string() const
{ return str(); }
};
好的,我知道这不是线程安全的,所有这些,我可能会被否决到地狱结束,但我在我正在使用的库中看到了以下内容(CERN 的根):
const char * myfunc(){
static std::string mystr;
/*populate mystr */
return mystr.c_str();
}
只有当你知道没有人会愚蠢到坚持指针时,这才有效。
这是一种无论如何都不会泄漏的临时方式。
在没有RVO/NRVO的世界里,这应该避免在C++11之前的标准库中进行复制构造。在带有字符串移动构造函数的 C++11 后库中,它仍然避免调用移动构造函数;这可能是一个微不足道的差异,但 OP 仍然在问如何做得更好。
(是的,我同意从字符串继承是丑陋的,但它确实有效。
#include <ctime>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
class DateString : public string {
public:
DateString() : string() {
stringstream ss;
time_t t = time(0);
struct tm * now = localtime(&t);
ss << now->tm_hour << ":";
ss << now->tm_min << ":";
ss << now->tm_sec << " ";
ss << now->tm_mday + 1 << " ";
ss << now->tm_mon + 1 << " ";
ss << now->tm_year + 1900;
append(ss.str());
}
};
int main()
{
cout << DateString() << endl;
return 0;
}
- C 字符串返回字符串的整数/双精度/长整型值
- std::hash<std::string> 可以为不同的字符串返回相同的值吗?
- Java 调用 dll 字符串返回类型方法
- 返回具有C++字符串返回值的函数的本地 C 字符串
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 尝试以随机字符(长读取)打印字符串返回结果
- 从字符串返回 i(索引)字
- 函数读取最大和min int值,并用文本字符串返回
- 如何将 YAML 节点中的序列作为字符串返回?
- 将注册表项读取为字符串返回数值
- 为什么我在尝试打印字符串返回时收到编译器错误?
- 使用 char*array 存储条形图的条形图,以便我可以动态制作它并作为字符串返回
- 字符串返回功能不起作用 - 'identifier is underfined'
- 将C 本地字符串返回到另一个功能
- 在MATLAB中仅接受INT32PTR时,将错误编号作为字符串返回
- 字符串流到字符串返回
- 字符串返回错误的长度
- 从共享指针矢量字符串返回值
- C++随机字符串返回意外结果
- 临时标准::字符串返回垃圾