从函数返回花括号初始化器列表:它被编译成什么?
Returning a braced initializer list from a function: What is it compiled down to?
例如,这里有一小段代码。
#include <iostream>
struct coordinate {
int x, y;
};
coordinate shift(coordinate p, int offset) {
return {p.x + offset, p.y + offset};
}
int main(int argc, char *argv[]) {
coordinate p {1, 2};
coordinate p_s = shift(p, 3);
std::cout << "x: " << p_s.x << "\ty: " << p_s.y;
return 0;
}
在函数 shift
中,我们看到 return 语句看似 return 初始化列表。
虽然我理解这在语义上意味着什么,但我想确认我是否理解它被编译成什么。
编译器是否将 shift
函数解释为这样?
shift(coordinate p, int offset) {
coordinate p_ {p.x + offset, p.y + offset};
return p_;
}
如果没有,那又如何呢?
感谢您的帮助。
我可能错了,但是... shift()
returns 一个临时 coordinate
,然后 p_s
是从该临时坐标复制构造的。
(我相信,大多数编译器可能会跳过中间人,并传递一个隐藏的引用,以便 shift()
直接构造 p_s
。)
它是相似的,虽然将等价写成构造函数表达式似乎更自然:
return coordinate{p.x + offset, p.y + offset};
很明显,它只不过是语法糖而已。也就是说,它不是return初始化列表,而是return使用花括号初始化列表语法构造的指定类型的新对象。
注意复制省略适用,所以当return值赋值给新构造的coordinate
时,中间的coordinate
将不会被构造(或者可能不会被构造,在旧的 c++ 版本中)。
您没有返回 "braced" 初始化列表,您返回的是用花括号初始化列表构建的结构,它是一个临时对象,因此 RVO 将适用。
不用担心。
例如,这里有一小段代码。
#include <iostream>
struct coordinate {
int x, y;
};
coordinate shift(coordinate p, int offset) {
return {p.x + offset, p.y + offset};
}
int main(int argc, char *argv[]) {
coordinate p {1, 2};
coordinate p_s = shift(p, 3);
std::cout << "x: " << p_s.x << "\ty: " << p_s.y;
return 0;
}
在函数 shift
中,我们看到 return 语句看似 return 初始化列表。
虽然我理解这在语义上意味着什么,但我想确认我是否理解它被编译成什么。
编译器是否将 shift
函数解释为这样?
shift(coordinate p, int offset) {
coordinate p_ {p.x + offset, p.y + offset};
return p_;
}
如果没有,那又如何呢?
感谢您的帮助。
我可能错了,但是... shift()
returns 一个临时 coordinate
,然后 p_s
是从该临时坐标复制构造的。
(我相信,大多数编译器可能会跳过中间人,并传递一个隐藏的引用,以便 shift()
直接构造 p_s
。)
它是相似的,虽然将等价写成构造函数表达式似乎更自然:
return coordinate{p.x + offset, p.y + offset};
很明显,它只不过是语法糖而已。也就是说,它不是return初始化列表,而是return使用花括号初始化列表语法构造的指定类型的新对象。
注意复制省略适用,所以当return值赋值给新构造的coordinate
时,中间的coordinate
将不会被构造(或者可能不会被构造,在旧的 c++ 版本中)。
您没有返回 "braced" 初始化列表,您返回的是用花括号初始化列表构建的结构,它是一个临时对象,因此 RVO 将适用。
不用担心。