gpt4 book ai didi

C++ 是否有类似 RVO 的东西用于将临时对象传递给函数?

转载 作者:行者123 更新时间:2023-11-27 23:49:54 26 4
gpt4 key购买 nike

使用 RVO 可以在不移动或复制的情况下从返回的对象创建对象。将对象传递给函数时是否可以做类似的事情?

class SomeClass {
int a;

public:
SomeClass(int _a) {a = _a; std::cout << "created\n";}
SomeClass(const SomeClass& source) {a = source.a; std::cout << "copied\n";}
SomeClass(SomeClass&& source) {a = source.a; std::cout << "moved\n";}
};

void create(SomeClass&& source) {
SomeClass some_object( std::move( source));
//p_some_object = new SomeClass( std::move( source));
//new( p_some_object) SomeClass( std::move( source));
}

// ...

create(SomeClass(15));

在这个例子中,结果是“created, moved”。 (GCC 5.4/C++11/-O3) new 或 placement-new 相同。没有分支什么的,为什么不移动就不能创建呢?

最佳答案

不保证编译器必须进行足够的内联和分析,以识别 source 引用的临时对象是不必要的。除此之外,甚至 RVO 也是为值语义而设计的;当 && 引用发挥作用时,我们无法保证。

碰巧的是,如果您遵循 C++ 函数参数的一般规则,GCC 会很好地处理您的情况:"If you need to copy the argument anyway, accept the argument by value."

按值接受意味着,在这种情况下,参数是作为调用的一部分构造的,不需要复制或移动(它可以,在 GCC 上,是“RVO”-ed)。

class SomeClass {
int a;

public:
SomeClass(int _a) {a = _a; std::cout << "created\n";}
SomeClass(const SomeClass& source) {a = source.a; std::cout << "copied\n";}
SomeClass(SomeClass&& source) {a = source.a; std::cout << "moved\n";}
};

void create(SomeClass some_object) {

}

int main() {
create(SomeClass(15));
}

如果你 try it , 仅显示 created 消息。

如果目标是让 create 为您构建对象,则使用带有参数转发的模板化函数,这样您就可以在 create 中构建它,例如

template<typename T, class... Args>
T create(Args&&... args) {
T some_object(std::forward<Args>(args)...);

return some_object;
}

int main() {
auto foo = create<SomeClass>(15);
}

通过将构造函数参数作为转发引用传递并在 create 中构造对象本身来解决问题,避免任何额外构造,as seen here .

关于C++ 是否有类似 RVO 的东西用于将临时对象传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47271704/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com