Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to avoid code duplication between syntactically identical const and non const functions that are not semantically identical

Tags:

c++

#include <iostream>
using namespace std;

class A 
{
    public:
    A() : x(0) {}
    // notice: not identical to const version but does update
    void FA() {std::cout << "A" << std::endl; x++;}
    void FA() const {std::cout << "const A" << std::endl;}
    private:
    int x;
};

class B
{
    public:
    B() : x(0) {}
    // notice: not identical to const version but does update
    void FB() {std::cout << "B" << std::endl; x++;}
    void FB() const {std::cout << "const B" << std::endl;}
    private:
    int x;
};

class C
{
    public:
    void FC()
    {
        bool condition = true; // should be set to a real condition

        if(condition)
        {
            a.FA();
        }
        b.FB();
    }

    void FC() const
    {
        bool condition = true; // should be set to a real condition

        if(condition)
        {
            a.FA();
        }
        b.FB();
    }

    private:
    A a;
    B b;
};

int main() {
    C c;
    c.FC();

    const C cc;
    cc.FC();

    return 0;
}

First, sorry for the lengthy title. How to avoid code duplication in class C in functions FC, FC const? given that you can not use the trick of casting this to const and calling the const FC version from the non const FC version because the non const FC's body actually will call functions that will do updates an are not identical to their corresponding constants.

like image 311
mkmostafa Avatar asked Jan 13 '17 13:01

mkmostafa


1 Answers

Let a template member function do the actual work. In other words: Try this:

class C
{
public:
    void FC()
    {
        FC_Impl( *this );
    }

    void FC() const
    {
        FC_Impl( *this );
    }

private:
    template <typename Self>
    static void FC_Impl( Self & self )
    {
      bool condition = true; // should be set to a real condition

      if(condition)
      {
          self.a.FA();
      }
      self.b.FB();
    }

    A a;
    B b;
};
like image 169
Ralph Tandetzky Avatar answered Nov 05 '22 14:11

Ralph Tandetzky