在C ++中实现返回计算值的最有效方法是什么?

时间:2011-10-03 13:03:05

标签: c++ templates rvalue-reference

随着返回值优化之上的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提供更清晰的解决方案。任何想法如何改进,还是我也应该独自留下?

2 个答案:

答案 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));
}