C ++ Templating vs Inheritance

I just understand how difficult it is to ask questions ... I hope I can give examples that are both accurate enough to demonstrate my problem and short enough not to damage everything ... At least there is the ability to edit.

So this is my situation at the moment. Of course, I changed this a bit in terms of logic / structure (and in terms of naming), trying to focus on the essence of my question:

// MyClass deals with lists (actually several data structures) of the // type MyType which should support different types and has to be // efficiently dealt with. Templating seems just right here class MyClass { ... void doSomething<class MyType>(vector<MyType> someList); ... // At some point I have to extract elements of the type MyType. // The extractor obviously depends on MyType but it is not possible to // Create a general version that could use templates itself // (unless I use a specialization for each possible MyType) // I am stuck between these two alternatives: // Possibility1: // Let the client pass the right extractor and template it. template<class Extractor, class MyType> void extract(const Extractor& extractor, const string& source, vector<MyType>* dest) { extractor.extract(source, dest); } // Possibility2: // Use a member _extractor of some base type that has to be set // to a specialization. The ExtractorBase has a virtual method // template<T> void extract(const string& source, vector<T>* myType) = 0 // with no definition that is only defined in subclasses wrt certain // postings. ExtractorBase _extractor; template<class MyType> void extract(const string& source, vector<MyType>* dest) { _extractor.extract(source, dest); } } 

At the moment, I prefer the opportunity1, because I do not need to mess with inheritance in Extractor for all MyType variants and the associated Extractor that I want to try in the future.

Extractors, on the other hand, may require complex code and several members (something like huge cards that map specific inputs to specific values). Thus, the use of patterns will not increase. In particular, using only the header file Extractors and, perhaps, even functors that need to be built in, is out of the question. It used to be a strong pointer to me that templating would only increase code complexity (the need to deal with instantiation, make life harder for client code, etc.), and that I should try to avoid this altogether.

Or is there a third possibility that I never thought of?

+6
source share
4 answers

Better go with the first option . It is cleaner and serviced.

Due to your comments, I conclude that you are making the wrong assumption for the second option:

 // The ExtractorBase has a virtual method // template<T> void extract(const string& source, vector<T>* myType) = 0; 

NO . It's impossible; The template function can never be virtual . Thus, in order to implement the second option, you should choose some dirty and hard-to-maintain methods, which is not a good idea.

+2
source

I see the first opportunity as more flexible.

In the second opportunity, I see no interest in the unnecessary encapsulating extractor as a member of the class. You also have more connections between MyClass and Extractor, which is not very good. templating reduces grip (in some way), so if you have a choice, it is better.

+1
source

You have a third option, specify a constructor for MyType that knows how to build itself from std::string . Or even better, a pair of iterators, so if you need to build a MyType sequence from a string, you can use a range.

+1
source

This is similar to the case of Strategy Template - your class has an operation, the implementation of which may differ.

Here are the trade-offs that I see in different approaches.

The solution to the template will avoid the declaration of an abstract interface class and use vtbl to figure out which implementation to use. But this will force you to block the application at compile time.

The inheritance solution will force you to declare an abstract interface class, as well as improve vtbl. search performance vtbl. But this will allow you to choose a runtime implementation at runtime.

Not knowing how critical the performance is for your application and how flexible you are, I would choose the inheritance solution because I like the clarity of defining an interface in an abstract class and its encoding.

0
source

Source: https://habr.com/ru/post/892109/


All Articles