Question

Is it possible to enable, disable class member functions?

Situation: I have a class with 2 types. Each Type has a own constructor. One Type need a function which must not have the other Type.

Example:

class A {
    enum struct TypeEnum : int {
        TYPE_1 = 1,
        TYPE_2 = 2
    };
    const TypeEnum type;

    int x;


    A(void) : type(TypeEnum::TYPE_1) { }
    A(int _x) : type(TypeEnum::TYPE_2) { 
        x = _x;
    }


    // function only for Type 2
    void A::operator += (const int& n) {
        x = x + n;
    }
};

int main() {
    A test1 = new A();
    A test2 = new A(1);

    test1 += 5;  // compiler error should be here
    test2 += 5;  // OK

    return 0;
}

Is where something possible like this:

class A {
    enum struct TypeEnum : int {
        TYPE_1 = 1,
        TYPE_2 = 2
    };
    const TypeEnum type;

    int x;


    A(void) : type(TypeEnum::TYPE_1) { }
    A(int _x) : type(TypeEnum::TYPE_2) { 
        x = _x;
    }


    // Is somethig like this realy impossible
    void A::operator += (const int& n) -> enable_if(type == TypeEnum::Type2) { // if not compile error
        x = x + n;
    }
};
Was it helpful?

Solution

You can use specialization:

enum struct TypeEnum : int {
    TYPE_1 = 1,
    TYPE_2 = 2
};

template<TypeEnum Type>
class A;

template<>
class A<TypeEnum::TYPE_1>
{
public:
    A(void) { }
};

template<>
class A<TypeEnum::TYPE_2>
{
public:
    A(int _x) { 
        x = _x;
    }
    int x;
    void operator += (const int& n) {
        x = x + n;
    }
};

int main() {
    A<TypeEnum::TYPE_1> test1;
    A<TypeEnum::TYPE_2> test2{1};

    test1 += 5;  // compiler error should be here
    test2 += 5;  // OK

    return 0;
}

OTHER TIPS

Maybe following may help:

class A {
public:
    explicit A(TypeEnum type) : type(type) {}
    virtual ~A() {}
protected:
    enum struct TypeEnum : int {
        TYPE_1 = 1,
        TYPE_2 = 2
    };
    const TypeEnum type;
};

class B : public A{
public:
    B() : A(TYPE_1) {}
};

class C : public A{
public:
    explicit C(int x) : A(TYPE_2), x(x) {}
    C& operator += (int n) { x = x + n; }
private:
    int x;
};

inheritance is here to reflect your case with a common type. it is not required else.

A thing you can do anyway:

B make_A() { return B{}; }
C make_A(int x) { return C{x}; }

int main() {
    auto test1 = make_A();  // B
    auto test2 = make_A(1); // C

    test1 += 5;  // compiler error should be here
    test2 += 5;  // OK

    return 0;
}

Strange that you didn't get compilation error here:

// function only for Type 2
void A::operator += (const int& n) {
    x = x + n;
}

I thought you wanted something like:

// function only for Type 2
A& operator += (int n) {
    x = x + n;
    return *this;
}

Answering on your question - C++ doesn't work like this. Nevertheless you can implement something similar with templates but I suggest not to do it unless it's just a test program.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top