It's safe as long as the mystruct
class is properly written, which means it supports copy construction and assignment and/or moving, and proper destruction, with the implied value semantics.
Put another way: "returning a vector" thing isn't the hard part here, it's making sure if you've got one T t1;
in any valid state, then you can say T t2(t1);
and/or T t3; t3 = t1;
and/or let any T
go out of scope / be delete
d and nothing bad or unexpected will happen. If your T
works for those scenarios, all's good to use it in a vector<T>
, even for returning by value from a function.
But which structs are safe for that? mystruct
is ok to copy/move construct/assign and destroy if it's careful to only make non-static
data members one of the following types, and any base classes do similarly:
simple data types like int
, double
, bool
etc.
self-managing types with value semantics, whether you wrote them yourself or they're provided by the Standard library or another library - e.g. std::string
, std::map
, std::vector
, std::list
etc. these know how to copy/move themselves properly
arrays of such types
std::shared_ptr
to data you do actually want shared ownership of, or std::unique_ptr<>
to data that can be moved but not copied
references, if it makes sense for a copy of the object to refer to the same place
other struct
s and/or class
es whose members and base classes satisfy the above conditions
But not raw pointers (unless to some deliberately shared data with a lifetime greater than the objects, e.g. a static const
variable or string literal): for new
/new[]
-ed data the object's meant to manage lifetime for, you need to write your own copy constructor and/or move constructor, copy assignment and/or move assignment operator, and destructor. It's usually much easier and better to use a std::shared_ptr<>
or std::unique_ptr<>
instead.