cpp: permit base member access only via derived by consumer

65 Views Asked by At

I have an application where Base is a factory class for objects that shall be created differently depending on a template pair. However, only very particular (countable infinite) number of template pairs make sense. For each of sensible pair, I have a (sometimes) templated Derived Factory class. The use of Base Factory is error prone due to the need for feasible correct choice of the template pair.

My question is: How can I prevent a consumer from using the Base Factory directly?

template<typename T1, typename T2>
class Base{
  Base()=delete;
public:
  // many public static routines
  T1 static foo(){ return 1; }
  T2 static bar(){ return 2; }
};

template<typename T1>
class Derived: public Base<T1,float>{
  // hopefully very little code, or none at all, as of now.
};

int main(){ // main is the consumer
  Base<int,float>::foo(); // prevent
  Derived<int>   ::foo(); // permit
}

I want the compiler to reject/thow/err the line with comment "prevent" in main. I want Base<..>::foo and Base<..>::bar not directly accessible by a consumer unless via access through Derived<..>. I had hoped that the virtual concept could be used for that purpose; however it does not transfer naturally from the non-static to the static case.

1

There are 1 best solutions below

4
wohlstad On BEST ANSWER

You can make the foo method protected, and expose it via the Derived class with a public using statement:

template<typename T1, typename T2>
class Base {
    Base() = delete;
protected:
    T1 static foo() { return 1; }
    T2 static bar() { return 2; }
};

template<typename T1>
class Derived : public Base<T1, float> {
public:
    using Base<T1, float>::foo;
};

int main() { // main is the consumer
    Base<int, float>::foo(); // prevent
    Derived<int>   ::foo(); // permit
}

Live demo - Godbolt