I have a constructor that accepts a std::istream &
and checks it before assigning one of the members (a std::istream &
). For example:
class Stream
{
public:
Stream(std::istream &is) : s_ {is.good() ? is : throw std::runtime_error {"Invalid input stream\n"}}
{}
private:
std::istream &s_;
};
The compiler complains that the constructor for std::basic_istream(const basic_istream &)
is deleted (understandably, since you can't copy streams). But, I don't see where any copying is being done here? It must be within the ternary operator, because
Stream(std::istream &is) : s {is} {}
with no checking works fine. Where is the std::istream
attempting to be copied? And how can I fix this?
This GCC bug 64372.
From cppreference on the conditional operator, we learn that if one operands of the conditional operator is a throw-expression, "[t]he result of the conditional operator has the type and the value category of the other expression." Thus, your use of the conditional operator should result in a type of std::istream&
, but GCC thinks it's std::istream
.
To work around this GCC bug, use a helper function:
class Stream
{
public:
Stream(std::istream &is) : s_ {validated_stream(is)}
{}
private:
std::istream &s_;
static std::istream &validated_stream(std::istream &is) {
if (!is.good()) throw std::runtime_error {"Invalid input stream\n"};
return is;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With