Hello,
I have the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
struct Serializable
{
virtual void Serialize(std::ostream& stream) const = 0;
};
struct Foo : public Serializable
{
int Data;
void Serialize(std::ostream& stream) const override
{
stream.write(reinterpret_cast<const char*>(&Data), sizeof(Data));
}
};
|
1 2 3
|
Foo foo;
std::ofstream file{"foo.dat"};
foo.Serialize(file);
|
The thing is, i want to, also, be able to pass an ostream rvalue reference to the
Serialize
function so that i can just do something like this:
1 2
|
Foo foo;
foo.Serialize( std::ofstream{"foo.dat"} );
|
But the problem is, if i change the
ostream&
parameter in the
Serialize
function to
const ostream&
(AFAIK this would allow rvalue reference arguments to convert to lvalue references), i wont be able to call the ostreams
write
function as that is a non-const funciton.
So instead i thought of overloading the function, in the base class, with one that takes an actual rvalue reference and then just calls the lvalue reference one, like this:
1 2 3 4 5 6 7 8
|
struct Serializable
{
virtual void Serialize(std::ostream& stream) const = 0;
virtual void Serialize(std::ostream&& stream) const
{
Serialize(stream);
}
};
|
But for whatever reason when i do this, and then try calling it with an rvalue reference:
1 2
|
Foo foo;
foo.Serialize( std::ofstream{"foo.dat"} );
|
The compiler gives me an error saying Foo has no function called
Serialize
that takes an rvalue reference.
Can someone explain to me why, exactly, the compiler cant find it? should it not be inherited?
Also does anyone have a good solution? The only one i can think of now is to have 3 functions, like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
struct Serializable
{
void Serialize(std::ostream& stream) const
{
SerializeImpl(stream);
}
void Serialize(std::ostream&& stream) const
{
SerializeImpl(stream);
}
protected:
virtual void SerializeImpl(std::ostream& stream) const = 0;
};
struct Foo : public Serializable
{
int Data;
void SerializeImpl(std::ostream& stream) const override
{
stream.write(reinterpret_cast<const char*>(&Data), sizeof(Data));
}
};
|
I've tested this & it works fine but i dont really like that the pure virtual function now has a different name than the function you call to serialize.