如果参数已存储,它们是否会被复制

Do arguments get copied if they're stored

本文关键字:是否 复制 参数 存储 如果      更新时间:2023-10-16

如果将参数存储在以下情况下,是否会复制它们

传递的文字字符串:

std::string globalStr;
void store(const std::string &str)
{
    globalStr = str;
}
store("Literal");

传递的变量字符串:

std::string globalStr;
void store(const std::string &str)
{
    globalStr = str;
}
store(varStr);

如果globalStr存储参考

std::string &globalStr;
void store(const std::string &str)
{
    globalStr = str;
}
store("Literal"); //Should this cause any problem?
store(varStr);

在上述任何一种情况下,C++是否进行了优化以防止生成不必要的副本?

在上述任何一种情况下,C++是否进行了优化以防止生成不必要的副本?

没有。

标准只是保证在第一种和第二种情况下,str的值将使用std::string::operator=()复制到globalStr

根据STL的实现,如果std::string使用写时复制优化,则可能会避免深度复制。

第三种情况将不会编译,因为引用在初始化后无法重新分配。

在前两个示例中,您正在绑定一个引用:void store(const std::string &str),它本身并不复制。

但在分配给全局变量的语句中:globalStr = str;-它复制它。

在您的第三个示例中,它不编译:std::string &globalStr;-引用需要初始化!


你可以试着写下:

void store(std::string &&str)
{
    globalStr = std::move(str);
}
store(std::move(varStr));

在任何涉及编译器优化的情况下:这取决于编译器。

如果编译器被编程为(并且可以在给定的情况下)向自己证明复制是不必要的,那么它就不会执行该复制。

对于您的特定问题,前两个方法都不能执行不必要的复制,因为输入是通过引用传递到store函数中的。当您将它们分配给globalStr时,它们会被复制,但该复制是必需的,因为globalStr是一个值变量;它是自己的副本,因此不能指向其他副本。

这一行:

std::string &globalStr;

无法编译。引用在声明时必须指定要引用的内容。