Reputation: 1661
I'm trying to initialize a object's member that cannot be assigned nor copied. I need some other tasks to be performed first and the initialization depends on it, so I have to delay it.
#include <boost/process.hpp>
class A{
std::unique_ptr<boost::process::child> child_;
std::unique_ptr<boost::process::pistream> is;
A(std::string exec, boost::process::context process_context){
// Stuff that needs to be done first
// ...
child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));
is = std::make_unique<boost::process::pistream>(child_->get_stdout()); // <- error
}
boost::process::child start_child(std::string exec, boost::process::context process_context);
};
The error I get from this is:
error C2280: 'std::basic_ios>::basic_ios(const std::basic_ios> &)' : attempting to reference a deleted function
If I understand this correctly, somewhere in that line a copy is happening, which isn't allowed. The unique pointers are not required. I just use them to avoid another error (no default initialization) but I would be happy to accept suggestions both with or without them.
Upvotes: 2
Views: 256
Reputation: 16824
The problem is that std::unique_ptr
wants ownership of the pistream
, so it tries to take a copy, which as you have discovered isn't allowed. If you think about it, this makes sense: you certainly don't want std::unique_ptr<b::p::pistream>
deleting _child
's stream in its destructor.
The easiest solution would be to just use a regular, non-owning pointer instead, say:
class A{
std::unique_ptr<boost::process::child> child_;
boost::process::pistream* is = nullptr;
A(std::string exec, boost::process::context process_context){
// ...
child_ = std::make_unique<boost::process::child>(start_child(exec, process_context));
is = &child_->get_stdout();
}
};
Of course, you'd want to check that is
is not nullptr
before actually using it, but the same is true for a unique_ptr
.
Upvotes: 3
Reputation: 393114
You can use boost::optional<>
for lazy initialization like this.
#include <memory>
#include <boost/optional.hpp>
struct pistream { };
struct child {
pistream& get_stdout() { return is; }
pistream is;
};
struct context { };
class A {
std::unique_ptr<child> child_;
boost::optional<pistream&> is;
A(std::string, context) {
// Stuff that needs to be done first
// ...
child_ = std::make_unique<child>();
is = child_->get_stdout();
}
};
Upvotes: 3