avoid code duplication in template functions used to distinguish between const and non-const

StackOverflow https://stackoverflow.com/questions/19979575

  •  30-07-2022
  •  | 
  •  

Domanda

In writing a program, I've come up with a piece of code that I cannot manage to make code-duplication free.

#include <iostream>

using namespace std;

class Presenter{
    public:
        template <typename T>
            void addField(T& t){
                cout << "do something that could happen to modify t" << endl;
            }

        template <typename T>
            void addField(const T& t){
                cout << "do something that cannot possibly happen to modify t" << endl;
            }
};

class Presented{
    public:
        Presented() : a(0), b(0.) {}
        void bind(Presenter& p){
            p.addField(a);
            p.addField(b);
            //...
        }
        void bind(Presenter& p) const {
            p.addField(a);
            p.addField(b);
            //...
        }
    private:
        int a;
        double b;
        //...
};

int main() {
    Presenter presenter;
    Presented p1;
    const Presented p2;
    p1.bind(presenter);
    p2.bind(presenter);
}

Here is a simple dummy program which shows the issue. As you see, the code of the two bind functions is (looks) exactly the same. Of course it is not, since two different functions (addField) are used, which only happen to share the name.

Nonetheless, I have been looking for a way to remove the need to verbatim write the void bind(Presenter& p) const.

Does anyone see a method for reaching the goal? I wasn't able to come up with one.

È stato utile?

Soluzione

Delegate to a template that can be called with a const or a non-const instance of Presented:

class Presented{
public:
    Presented() : a(0), b(0.) {}
    void bind(Presenter& p){
        bindImpl(p, *this);

    }
    void bind(Presenter& p) const {
        bindImpl(p, *this);
    }
private:
    template<typename P>
    static void bindImpl(Presenter& p, P& presented)
    {
        p.addField(presented.a);
        p.addField(presented.b);
    }

    int a;
    double b;
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top