从内联函数返回字符串时会创建多少个临时对象?

时间:2013-12-03 11:06:24

标签: c++ string inline-code

请考虑以下代码:

QSqlQuery *queryQt; // represents a row in a database table

inline std::string getCString(size_t col) {
     return queryQt->value(col).toString().toStdString();
}

其中queryQt->value(col).toString()表示数据库中行的特定列的字符串值。

让我们假设编译器已经进行了所有优化。

问题:是以下代码:

std::string a = T.getCString(0);

等于

std::string a = queryQt->value(col).toString().toStdString();

std::string temp = queryQt->value(col).toString().toStdString();
std::string a = temp;

问题更新:

如果我将const添加到返回类型中会有所作为吗?

2 个答案:

答案 0 :(得分:3)

以下代码是初始化 a而未分配

std::string a = T.getCString(0);

相当于

std::string a(T.getCString(0)); // Construct "a" with return value of function.

std::string a(std::string(queryQt->value(0).toString().toStdString()));

这意味着从函数返回时会有std::string的复制结构,而从返回值构造a时会有另一个复制结构。所以2份。

但是在C ++ 11编译器中,在构造返回值时将使用移动构造,而a构造的std::string对象是临时构建的。这意味着只有2个动作而不是2个副本。

最后因为copy elision optimizations,编译器很可能将这些副本全部放在一起,只需在std::string中直接构造a,就不会产生任何副本。

内联函数与正在制作的副本数量无关。将返回类型更改为const将阻止移动构造,因为您无法从const对象移动。

Look at this live example using my noisy class

答案 1 :(得分:1)

相当于

std::string temp = queryQt->value(col).toString().toStdString();
std::string a = temp;

理论上,至少。根据您的实际编译器及其设置,即使使用inline关键字,该函数也可能无法内联。大多数现代编译器(在发布设置上)也将优化代码

std::string a = queryQt->value(col).toString().toStdString();