假设我有一个简单的函数returnString,它按值返回一个字符串:
std::string returnString() {
std::string s;
// Use s in such a way to defeat return value mandatory copy-elision
return s;
}我还有一个要堆的函数--分配这个结果。很简单。
void caller() {
std::string* heap_allocated_string = new std::string(returnString());
}但是,不要考虑std::string,而是考虑任意类型的T。我相信,按照语言规则,以下两种说法是正确的。是吗?
一般来说,对于泛型类型,是否有更好的方法来做到这一点,而不修改被调用的函数呢?
发布于 2022-08-31 16:29:55
In C++14,我认为这并不理想,因为对于某些类型,如果移动ctor不是空闲的或未定义的,我们可能要做不必要的工作,而不是直接在堆上构建。
定义“不理想”。
如果必须通过一个按值返回的工厂函数来构造对象,并且您想要堆--而不是分配对象,那么您必须“不修改被调用的函数”来完成这个任务,那么这就和它将要得到的一样好。
另外,您不必担心在C++14中缺少复制/移动。原因是在C++14中通过值返回一个不可复制、不可移动的对象(几乎)是不可能的。从技术上讲,有一种方法(通过使用return语句中的列表初始化语法),但是如果函数是按照您的说明编写的,那么它返回的任何类型都必须是可复制的或可移动的。
此外,您端的new表达式甚至不需要命名RVO;这部分只是临时的,编译器没有理由不能优化这个迁移。
因此,基本上,要编译函数必须有一个复制/移动构造函数,并且为了所有实际目的,任何复制/移动都将在您的末端进行优化。所以没什么好担心的。
https://stackoverflow.com/questions/73558705
复制相似问题