I have a function that takes an std::optional
void foo(const std::optional<T>& opt);
But copying T is expencive.
Does this create a copy of T?
If so, how can I not create a copy?
I have a function that takes an std::optional
void foo(const std::optional<T>& opt);
But copying T is expencive.
Does this create a copy of T?
If so, how can I not create a copy?
As clarified by your follow up comment, you are calling the function foo like this:
T t;
...
foo({t});
In this case, the answer is yes. A copy of t will be created. To avoid that, you can use std::reference_wrapper to avoid copying:
void foo(const std::optional<std::reference_wrapper<const T>> &optT) {
...
}
With these changes to the function, calling the it in the same manner will not result in creation of a copy.
Yes, std::optional stores a copy of whatever you pass to it. The C++17 standard explicitly prohibits storing references in std::optional. See: https://en.cppreference.com/w/cpp/utility/optional#:~:text=There%20are%20no%20optional%20references
As suggested by others, passing std::optional<std::reference_wrapper<const T>> is one way to avoid making copies.
void foo(const std::optional<std::reference_wrapper<const T>>& opt) {
if (opt) {
// Do something.
}
}
T t;
foo(t);
But consider that the C++ committee had good reasons for disallowing references in std::optional. For instance, an "optional reference" essentially describes what a plain pointer does, and plain pointers don't suffer from the long type name.
void foo(const T* opt) {
if (opt) {
// Do something.
}
}
T t;
foo(&t);