返回表达式中 `{}` 的含义

19

我无意中发现以下代码是可以编译通过的:

#include <string>
#include <iostream>

class A{
    int i{};
    std::string s{};
    public:
        A(int _i, const std::string& _s) : i(_i), s(_s) {
            puts("Called A(int, const std::string)");
        }

};

A foo(int k, const char* cstr){
    return {k, cstr};           // (*)
}

int main(){
    auto a = foo(10, "Hi!");
    return 0;
}

我感兴趣的是 (*)。我猜测函数 foo 等价于:

A foo(int k, const char* str){
    return A(k, cstr);
}

然而,在 (*) 中,这种机制是否有特殊的名称?还是简单地由于返回类型,编译器知道要调用哪个构造函数?


20
它被称为“复制列表初始化”,这是一种方便的返回内容的方式。 - Nathan Pierson
2
这可能取决于您所参考的特定C++标准。请参阅此C++参考资料,并阅读n3337或一些更新的C++标准。 - Basile Starynkevitch
谢谢你们两个。@NathanPierson 请随意将您的评论发布为答案,这样我就可以接受它了。 - Ronaldinho
2
请注意,在最近的C++标准中,编译器将执行(通常在旧标准中执行)一些相当巧妙的魔法(复制省略),使这成为返回对象的特别高效的方式。 - user4581301
相关问题 - αλεχολυτ
2个回答

26

return {k, cstr}; 的意思是 {k, cstr} 是返回值的初始化器。同时,它表示“返回函数返回类型的对象,该对象用 kcstr 初始化,这意味着具体行为取决于返回对象的类型”。

返回值可以通过两种不同的方式进行初始化:


16

这是一种特定形式的复制列表初始化

请参阅该参考资料中的第8条:

在以下情况下执行列表初始化:

...

复制列表初始化(显式和非显式构造函数都将被考虑,但只有非显式构造函数可以被调用)

...

  1. 在带有花括号初始化列表作为返回表达式并且列表初始化初始化了返回的对象的返回语句中

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接