But isn't there a conceptual way to solve the seperation? For example
something different than templates?
If you are looking for a portable c++ alternative to templates, their is simply no such thing that provides the sheer power that templates do. That aside, let's try to solve your problem.
You can simply package functions into a separate class which you can implement in any other header. We have two choices here, adding that proxy class as a member to the base class or using inheritance.
Choice A (directly including as a member)
Using this method you come across a problem, their is no way to directly access the functions. You can't overload the .
operator! One way to deal with this is a proxy function that simply returns a reference to the member variable. Here's a minimal working example:
#include <iostream>
using namespace std;
// forward declaration
template <typename T>
class B;
template <typename T>
class A {
public:
// allows friendship regardless of the type instantiated with class A
template <typename U>
friend class B;
A(int a) : a_(a), funcs_(this) {}
// this could be named anything
B<T>& utils() { return funcs_; }
private:
int a_;
// proxy class instance, should probably be static
B<T> funcs_;
};
// this class could be modifed to accept any type but i did this for simplicity
template <typename T>
class B {
public:
explicit B(A<T>* base) : base_(base) {}
// function implementations go here...
void print() { std::cout << base_->a_; }
private:
A<T>* base_;
};
int main() {
A<int> testA(23);
testA.utils().print();
return 0;
}
Choice B (inheritance)
Using this method you will be able to directly access the functions, but it comes at the cost of using inheritance, which i know some people would preer not to use over choice A. Here is a working example:
#include <iostream>
using namespace std;
// forward declaration
template <typename T>
class B;
template <typename T>
class A : public B<T> {
public:
// allows friendship regardless of the type instantiated with class A
template <typename U>
friend class B;
A(int a) : a_(a), B(this) {}
private:
int a_;
};
// this class could be modifed to accept any type but i did this for simplicity
template <typename T>
class B {
public:
explicit B(A<T>* base) : base_(base) {}
// function implementations go here...
void print() { std::cout << base_->a_; }
private:
// pointer to base class
A<T>* base_;
};
int main() {
A<int> testA(23);
testA.print();
return 0;
}
If it were my choice i would most likely use Choice B, I wouldn't want to give the client the need to explicitly call a function just too call another function. You could obviously use some tricks involving typedef
and bind
but I think that adds unnecessary overhead.