overloaded base method not inherited ?

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.
Last edited on
I've tested this & it works fine but i don't really like that the pure virtual function now has a different name than the function you call to serialize.

Note that the standard library does this nearly everywhere as a matter of separation-of-concerns. See:
http://www.gotw.ca/publications/mill18.htm
In a widely used library interface, this may be a wise guideline to follow.
Topic archived. No new replies allowed.