may I know if there is more efficient way of constructing below variant?
#include <variant>
#include <string>
class Person{
public:
Person(std::string name, int age, std::string school)
:name_(name), age_(age){}
private:
std::string name_;
int age_;
};
class Dummy1{};
class Dummy2{};
using PersonVariant = std::variant<Person, Dummy2, Dummy1>;
int main() {
Person person("jack", 10, "school");
PersonVariant pv(person); // does this involve an uneccessary copy?
}
The construct seems involve an unnecessary copy.
CodePudding user response:
Most efficient way is to use in-place constructor:
PersonVariant pv{std::in_place_type<Person>, "jack", 10, "school"};
CodePudding user response:
PersonVariant pv(person); // does this involve an uneccessary copy?
Yes. person
is an lvalue so a copy will be made to construct the Person
object in the variant. You have a couple of options to make this better. The simplest fix is to use
PersonVariant pv(Person("jack", 10, "school"));
Which will construct a temporary object that will get moved into pv
.
You can also use variants in place construction to pass the values to construct the Person
object directly inside the variant like
PersonVariant pv(std::in_place_type<Person>, "jack", 10, "school");
There is no moving or copy of a Person
in this case and at most you would have a move or copy of the parameters to construct the Person
object but you have that cost no matter what so this can be considered the most efficient way to do this.
For completeness sake you could also use
Person person("jack", 10, "school");
PersonVariant pv(std::move(person));
which will force person
to be moved into the variant like PersonVariant pv(Person("jack", 10, "school"));
does but now person
is a moved from object and you can only reuse it as it is essentially an empty object (in the context of the values of the members).