Can someone give a hint how does compiler process expressions such as
class DerivedA: public ParentTemplateClass<DerivedA>{
}
For mee it looks like:
this boy's father is a "son" of this boy
I mean it's not obvious for me how "parsing" of the class DerivedA can be completed WITHOUT knowing the exactly "description" of parent class. Seems' it can not. So parent class must be processed before children, but in such situation parent depends on children..and I'm stuck there.
Yeah there some articles on the web which describe usage of such thing, e.g. an article about Curiously Recurring Template Pattern (
http://en.wikibooks.org/wiki/More_C++_Idioms/Curiously_Recurring_Template_Pattern) but that's not some kind of standart or smth near. There must be clear behaviour description such as operations ordering isn't it?
ANSWERED:
Thnx to everyone. Yeah forward decl analogy seems legit for me to stop damaging my brain. Templates are still state of art for me cause of its hidden sublanguage nature and i cant just g++ -E :)
After your code says class DerivedA, the symbol DerviedA is declared. At the point it can be used as a template parameter. C++ compilers do several passes on the code, so at that point in parsing the compiler will "believe" that your intention was correct and that it will eventually get the definition of that class (when it is about to instantiate the template, i.e. you actually use that type). If not, it will complain at that point. A similar thing happens if you used a forward declared class in a declaration but didn't provide a definition before using it.
At the point at which the template is instantiated, DerivedA is incomplete; it has been declared, but not fully defined. Incomplete types can be used in various ways - for example, you can declare pointers or references to them, declare functions with them as return or parameter types, and a few other things. You can't create objects, inherit from them, access their members, or in general do anything that requires more information than just the class name.
As long as the class template only does these things, there is no problem.
I think to understand how this could work, you need too understand more about C++ templates in general, than just the Curiously Recurring Template Pattern. Someone else can probably answer this better than me, but I know that C++ can't fully parse a template class definition by itself. It instantiates the template each time it is used in the code. If each class was in a separate include file, think of it like this:
#include "ParentTemplateClass.h" // C++ initially validates the template class definition's syntax.
#include "DerivedA.h" // First use of ParentTemplateClass -
// at this point it becomes fully instantiated.
The C++ parser will initially validate the template's syntax when it sees the template definition. Then, when the template is used as a base of DerivedA, the parsing continues and the template is fully instantiated. This is, of course, a simplified view of the parsing that the C++ compiler will do, and I'm sure the details vary by compiler. See also http://womble.decadent.org.uk/c++/template-faq.html#disambiguation.
Related
I have a large class which basically handles one buffer of variable (numeric) datatype. So it seems a good choice to use a class template with this datatype as the only parameter. I'm not experienced in C++ and I wonder/worry a bit about the "footprint" such a template makes in my code.
There are three implications of templates which in my (C++ unexperienced) eyes are not necessary and make code ugly. I tried to avoid them, but neither did I find a good example how to do it nor did I manage to find it out by myself.
So the goal of this question is: Can you either confirm the following statements or give a counterexample?
When using a class template, all class methods have to go into the header file. Even if they have no templated type in their interface or implementation.
When using a static method or member of the class, I always have to specify a template parameter (MyClass< double > :: MY_STATIC), even if the templatization does not affect any of the static properties of the class.
When using the class as a parameter for a function, I always have to give a template parameter, even when this function does not access any of the templated members? (function myFunc(MyClass< double> & myClass){ do something } )
As a general rule, don't have functions/data members in a template class which does not use the template parameters. Have a base class, put all non-template related things there, your template class should derive from it.
To answer your questions:
yes, everywhere where you need to instantiate the template, you need to see the full definition of the class and it's functions
yep, but put that into the base class
yes, see above
EDIT: One of the reasons to move to base class is code bloating (this expression actually exist, you can google it for more info): If you don't move the template unrelated code to a base class, the very same template independent code will be copied for all instantiation of your template, which means a lot of unnecessary code. If you put it to a base class, you will only have this code once.
Yes. On the plus side, the code is only generated when the metod is actually used for the specialization.
Yes. However, there is no (other then design choice) need for a static method to be a memeber of the templated class if it has no use for the templated parameter.
Yes. The size and memory layout of the structure is determined by the template parameter.
What is considered "good practice" in handling unwanted data types for templated classes?
Let's say we have a function in a templated class that does number multiplication, but the driver file for the class declares an instance of the class with Type string.
I've been given the argument that this is a "personal problem" for whoever's creating the driver file, and that all that needs to be done on your part is proper function prologues in the header/implementation files.
I'm wondering if there is a general practice used with templates regarding this issue. Do you check your Types in a class before handling them (I guess, to a certain extent that defeats the purpose of a template), or do you define behavior for specific types (though this also seems like a defeat of purpose)?
Or do you simply document your code correctly and let the programmer who uses your class take the precautions?
I'd generally use something like Boost/C++11 static_assert to assert the properties you want This will not only let you assure that it's numeric, but has things like is_signed and is_integer to assure more detail about the type, if you need/want to.
Note: This is a follow-up question to this.
I have a group of template classes that do completely different things in completely different ways using completely different datatypes. They do, however, share common method names. For example, Get(), Set(), Resize(), etc. are valid methods for each of the classes in question. Additionally, they accept arguments in the same order. This allows for generalized non-friend, non-member functions to work on each of the classes. A simplified example:
template <typename Class, typename Datatype>
void Insert(const Class<Datatype>& Object, const std::size_t Index, const Datatype Value)
{
Object.Resize(Object.Size() + 1);
for (std::size_t CurrentIndex = Object.Size() - 1; CurrentIndex > Index; CurrentIndex--)
{
Object.Set(CurrentIndex, Object.Get(CurrentIndex - 1));
}
Object.Set(Index, Value);
}
Right now, I'm just relying on my own memory to define all the appropriate methods properly. Is there a way to have the compiler enforce the definition of the proper methods? If not, is there a better way to do this?
What you are looking for is called "concepts" and used to be a feature in C++0x but got dropped from the new standard.
There are some implementations for C++03 out there, but they are harder to use and might be not worth the trouble. e.g. Boost Concept Checking
gcc also has the --enable-concept-check option although I'm not entirely sure how that works with user code.
The compiler already enforces the definition of those methods by refusing to let you instantiate the template for types that don't provide the necessary methods.
Unfortunately, compilers' error messages for uninstantiable templates are often difficult to decipher.
You can document the type requirements in comments. Take a look at how the C++ standard defines type requirements like Assignable, CopyConstructible, EqualityComparable, LessThanComparable, and the requirements for types in the standard containers.
The compiler will enforce the correct interface by failing to compile any call to a nonexistent function; perhaps the problem is that the error messages are too cryptic?
You could define a base class which declares the required interface as non-virtual functions. The base class functions have no definitions (except where it makes sense to have an optional function with a default implementation).
Then, if the template argument derives from this base class, failure to implement a required function will cause a link error (due to attempting to call the base class functions, which are not defined). This will most likely be easier to diagnose than a typical template-related compile error.
You could go one step further and include a compile-time check that the template argument is derived from the base class; I'll leave that as an exercise for the reader. Or it might be better to just document the purpose of the base class, and leave it up to the user whether to use it or not.
You can use an interface.
See this question: How do you declare an interface in C++?
Should I define an interface which explicitly informs the user what all he/she should implement in order to use the class as template argument or let the compiler warn him when the functionality is not implemented ?
template <Class C1, Class C2>
SomeClass
{
...
}
Class C1 has to implement certain methods and operators, compiler won't warn until they are used. Should I rely on compiler to warn or make sure that I do:
Class C1 : public SomeInterfaceEnforcedFunctions
{
// Class C1 has to implement them either way
// but this is explicit? am I right or being
// redundant ?
}
Ideally, you should use a concept to specify the requirements on the type used as a template argument. Unfortunately, neither the current nor the upcoming standard includes concepts.
Absent that, there are various methods available for enforcing such requirements. You might want to read Eric Neibler's article about how to enforce requirements on template arguments.
I'd agree with Eric's assertion that leaving it all to the compiler is generally unacceptable. It's much of the source of the horrible error messages most of us associate with templates, where seemingly trivial typos can result in pages of unreadable dreck.
If you are going to force an interface, then why use a template at all? You can simply do -
class SomeInterface //make this an interface by having pure virtual functions
{
public:
RType SomeFunction(Param1 p1, Param2 p2) = 0;
/*You don't have to know how this method is implemented,
but now you can guarantee that whoever wants to create a type
that is SomeInterface will have to implement SomeFunction in
their derived class.
*/
};
followed by
template <class C2>
class SomeClass
{
//use SomeInterface here directly.
};
Update -
A fundamental problem with this approach is that it only works for types that is rolled out by a user. If there is a standard library type that conforms to your interface specification, or a third party code or another library (like boost) that has classes that conform to SomeInterface, they won't work unless you wrap them in your own class, implement the interface and forward the calls appropriately. I'm somehow not liking my answer anymore.
Absent of concepts, a for now abandoned concept (pun not intended, but noted) for describing which requirements a template parameter must fulfill, the requirements are only enforced implicitly. That is, if whatever your users use as a template parameter doesn't fulfill them, the code won't compile. Unfortunately, the error message resulting from that are often quite gibberish. The only things you can do to improve matters is to
describe the requirements in your template's documentation
insert code that checks for those requirements early on in your template, before it delves so deep that the error messages your users get become unintelligibly.
The latter can be quite complicated (static_assert to the rescue!) or even impossible, which is the reason concepts where considered to become a core-language feature, instead of a library.
Note that it is easy to overlook a requirement this way, which will only become apparent when someone uses a type as a template parameter that won't work. However, it is at least as easy to overlook that requirements are often quite lose and put more into the description than what the code actually calls for.
For example, + is defined not only for numbers, but also for std::string and for any number of user-defined types. Conesequently, a template add<T> might not only be used with numbers, but also with strings and an infinite number of user-defined types. Whether this is an unwanted side-effect of the code you want to suppress or a feature you want to support is up to you. All I'm saying is that it is not easy to catch this.
I don't think defining an interface in the form of an abstract base class with virtual functions is a good idea. This is run-time polymorphism, a main pillar classic OO. If you do this, then you don't need a template, just take the base class per reference.
But then you also lose one of the main advantages of templates, which is that they are, in some ways, more flexible (try to write an add() function classic OO which works with any type overloading + in) and faster, because the binding of the function calls take place not at run-time, but during compilation. (That brings more than it might look like at first due to the ability to inline, which usually isn't possible with run-time polymorphism.)
I am a "C" programmer that knows just the tiniest bits of C++. I am having a look at some open source C++ code trying to understand some things that it is doing. I can work out most of it but sometimes there is syntax I don't recognise and I'd like to be able to "look up" the meaning of the syntax so I can read just enough to understand that bit of C++. But you can't just type a bunch of symbols into google - or whatever to find out the meaning in C++. Any suggestions of how I can do this in general?
The specific syntax I'm struggling with right now is the following:
void Blah<BOARD>::Generate(SgPoint p)
What is the significance of the <BOARD> in this context? What should I look up in order to understand it?
void Blah<BOARD>::Generate(SgPoint p)
Generate is a member function of a class template Blah .
BOARD is the name of the parameter.
Your class Blah could be like this :
template <typename BOARD>
class Blah
{
//...some code
void Generate(SgPoint p);
//...some more code
};
Blah is most likely a templated class, Generate is a method from this class and this is most likely the first line of the method definition.
Edit: Oh and BOARD is the template parameter (can be type or integral value).
This is the Generate method of the Blah class template specialized for template parameter BOARD.
In other words, what follows is the actual code that gets called when the Blah template is used to process an instance of class BOARD.
Other classes may get processed in a different way if separate specializations exist for them, or via the default non-specialized implementation of Generate, or not at all if there is no default and no specialization for them - in which case, an attempt to call that function will not compile.
There is a short introduction to the topic of template specialization here.
You run into C++ templates - very neat feature!