随着返回值优化之上的rvalue引用的出现,实现这样的核心函数的最有效方法是什么?我该如何改进这种实施方式,还是应该不管它呢?
template <typename T>
string
to_string(const T& t)
{
stringstream ss;
ss << t;
return ss.str();
}
显然,如果可以,我想避免复制或分配内存。 TIA。
编辑:请向D. Rodriguez索取详细答案。现在,我的第二部分是我的问题。有没有办法改善这个?
#define to_cstr( T ) (to_string( T ).c_str())
当然,如果可以,我想避免使用MACRO,但是如果我复制并粘贴上面的模板代码来返回ss.str()。c_str()和const char *,那么临时就不够长;虽然代码似乎运行,但valgrind抱怨(红灯)。
对于to_cstr(),我无法为上面的MACRO提供更清晰的解决方案。任何想法如何改进,还是我也应该独自留下?
答案 0 :(得分:7)
只是不管它,它是否有效。即使使用C ++ 03编译器,编译器也会优化副本。
编译器基本上会确保调用代码to_string
中的对象,to_string
的return语句和ss.str()
的return语句都采用完全相同的内存位置。这反过来意味着没有副本。
在标准强制要求之外,calling conventions为函数的return语句,该函数返回一个对象,该对象不适合我所知道的所有32/64编译器中的寄存器(包括VS,gcc, intel,suncc)将传递一个指向内存中该函数构造返回对象的位置的指针,这样代码将被内部转换为以下行中的某些内容:
// Not valid C++! Just for illustration purposes
template <typename T>
to_string( uninitialized<string>* res, const T& t ) {
stringstream ss;
ss << t;
stringstream::str( res, &ss ); // first argument is return location
// second argument is `this`
}
答案 1 :(得分:0)
现在,我的第二部分是我的问题。有没有办法改善这个?
#define to_cstr( T ) (to_string( T ).c_str())
当然,如果可以,我想避免使用MACRO,但是如果我复制并粘贴上面的模板代码来返回ss.str()。c_str()和const char *,那么临时就不够长;虽然代码似乎运行,但valgrind抱怨(红灯)。
您可以让编译器为您在调用者作用域中创建一个临时值,以便临时生命周期对应于创建临时表达式的表达式。方法如下:
struct TmpStr {
mutable std::string s;
};
template<typename T>
char const* to_cstr(T value, TmpStr const& tmp = TmpStr()) {
tmp.s = to_string(value); // your original function
return tmp.s.c_str(); // tmp lives in the scope of the caller
}
int main() {
printf("%s\n", to_cstr(1));
}