The C ++ aspect that periodically disappoints me is a solution where templates are suitable for header files (traditionally describing the interface) and implementation files (.cpp). Templates often need to go in the header, exposing the implementation, and sometimes pulling out additional headers that previously only needed to be included in the .cpp file. I recently ran into this problem and a simplified example of this is shown below.
#include <iostream> // for ~Counter() and countAndPrint() class Counter { unsigned int count_; public: Counter() : count_(0) {} virtual ~Counter(); template<class T> void countAndPrint(const T&a); }; Counter::~Counter() { std::cout << "total count=" << count_ << "\n"; } template<class T> void Counter::countAndPrint(const T&a) { ++count_; std::cout << "counted: "<< a << "\n"; } // Simple example class to use with Counter::countAndPrint class IntPair { int a_; int b_; public: IntPair(int a, int b) : a_(a), b_(b) {} friend std::ostream & operator<<(std::ostream &o, const IntPair &ip) { return o << "(" << ip.a_ << "," << ip.b_ << ")"; } }; int main() { Counter ex; int i = 5; ex.countAndPrint(i); double d=3.2; ex.countAndPrint(d); IntPair ip(2,4); ex.countAndPrint(ip); }
Please note that I intend to use my actual class as a base class, hence a virtual destructor; I doubt this is important, but I left it in Counter just in case. The result obtained above is equal to
counted: 5 counted: 3.2 counted: (2,4) total count=3
Now the Counter declaration of the class declaration can go in the header file (for example, counter.h). I can put the dtor implementation, which requires iostream, in counter.cpp. But what to do for the countAndPrint() member function template, which also uses iostream? This does not need to be used in counter.cpp, since it must be created outside of the compiled counter.o. But including it in counter.h means that something, including counter.h, also in turn includes iostream, which just seems wrong (and I agree that I just need to overcome this disgust). I could also put the template code in a separate file (counter.t?), But that would be a bit surprising for other code users. Lakos doesnβt actually fit into this as we would like, and C ++ FAQs do not go into best practices. So what I need:
- Are there any alternatives for dividing the code into the ones I suggested?
- in practice, what works best?
source share