通过引用传递 std::optional<T> 是否真的节省了复制?
Does passing an std::optional<T> by reference actually save copying?
我知道标准不支持 std::optional<T&>
。这个问题是关于传递 std::optional<T>&
是否有任何性能优势
此处转载示例代码 (https://godbolt.org/z/h56Pj6d6z)
#include <ctime>
#include <iomanip>
#include <iostream>
#include <optional>
void DoStuff(std::optional<std::string> str) {
if (str) std::cout << "cop: " << *str << std::endl;
}
void DoStuffRef(const std::optional<std::string>& str) {
if (str) std::cout << "ref: " << *str << std::endl;
}
int main() {
std::optional<std::string> str = {};
DoStuff(str);
DoStuffRef(str);
str = "0123456789012345678901234567890123456789";
DoStuff(str);
DoStuffRef(str);
}
(我的实际用例对于复杂的用户定义类型是可选的,但我希望长字符串在编译器方面也能做到相同)
在这种情况下,与 DoStuff
相比,DoStuffRef
是否真的节省了任何复制工作?
我试图查看 godbolt 输出,但我对汇编的了解不足,无法确定。我确实看到在 DoStuff
的情况下,似乎创建了一个临时 std::optional<T>
,但在 DoStuffRef
中不存在,所以我怀疑是的,传递了一个 optional
通过引用保存一些复制
感谢帮助!
如果您通过实际 std::optional<std::string>
那么是的,不会有副本。但是,如果您只传递 std::string
,则必须首先构造临时可选,从而生成字符串的副本。
DoStuffRef
当参数已经是 std::optional<std::string>
时保存一个额外的副本(如您的示例)。
但是,如果你直接传递一个std::string
,那么如果这两种情况,都应该构造一个std::optional
,涉及字符串的copy/move构造函数。
我知道标准不支持 std::optional<T&>
。这个问题是关于传递 std::optional<T>&
是否有任何性能优势
此处转载示例代码 (https://godbolt.org/z/h56Pj6d6z)
#include <ctime>
#include <iomanip>
#include <iostream>
#include <optional>
void DoStuff(std::optional<std::string> str) {
if (str) std::cout << "cop: " << *str << std::endl;
}
void DoStuffRef(const std::optional<std::string>& str) {
if (str) std::cout << "ref: " << *str << std::endl;
}
int main() {
std::optional<std::string> str = {};
DoStuff(str);
DoStuffRef(str);
str = "0123456789012345678901234567890123456789";
DoStuff(str);
DoStuffRef(str);
}
(我的实际用例对于复杂的用户定义类型是可选的,但我希望长字符串在编译器方面也能做到相同)
在这种情况下,与 DoStuff
相比,DoStuffRef
是否真的节省了任何复制工作?
我试图查看 godbolt 输出,但我对汇编的了解不足,无法确定。我确实看到在 DoStuff
的情况下,似乎创建了一个临时 std::optional<T>
,但在 DoStuffRef
中不存在,所以我怀疑是的,传递了一个 optional
通过引用保存一些复制
感谢帮助!
如果您通过实际 std::optional<std::string>
那么是的,不会有副本。但是,如果您只传递 std::string
,则必须首先构造临时可选,从而生成字符串的副本。
DoStuffRef
当参数已经是 std::optional<std::string>
时保存一个额外的副本(如您的示例)。
但是,如果你直接传递一个std::string
,那么如果这两种情况,都应该构造一个std::optional
,涉及字符串的copy/move构造函数。