In C++ for a template T variable for a class.
What would it's binding time be?
I'm thinking compile time because it would need to know what value is being passed to it before binding it to a value/address.
Yes. You could think of templates as "class factories", the result of using a template is a class that has been specialized for the specific types you use in the template. So this is all compile-time specialization.
Related
I am writing a template to abstract a buffer class. Can I pass conditional_variables as parameters to the template or do they need to be global? What is the best way to template this to abstract it without explicitly 'hardcoding' it in?
You can use references to them:
template<std::condition_variable &> class F;
(or pointers, analogously). But this actually makes very little sense for the arguments to such a template should be very static and compile-time known, i.e. practically the very same globals.
So there are 3 types of template parameters:
type
non-type
template
SO if the use of templates is to serve as a "class" to classes...in other words a template is to a class what a class is to an object... and provide things such as data type independence, why would I want to use a type parameter template?
for example, why would I ever want to use something like
template <int n = 1>
?
Thank you
There are plenty of uses, C++ templates are not just a mean to "get away with types".
std::array<T, N> is one example : capture the array size at compile time
Many examples in the standard library : see std::get<> to access tuple elements
Integrals arguments can server as an input for MTP algorithms (and consequently, allow C++ templates to form a complete Turing machine, which is a major property of the language ):
Example of a compile-time factorial :
template <int n>
struct factorial {
enum { value = n * factorial<n - 1>::value };
};
template <>
struct factorial<0> {
enum { value = 1 };
};
As I understand your question, you have a relationship like:
(meta-template)->template->class->object
Meta templates are templates which can act as a kind of template generator. This is not really the truth but is also not really the truth that a template is a class generator.
Templates can be used as a class generator. This is what often results in multiple copies of the same code in the binary and is sometimes not what is really useful.
But a template can do much more!
Templates allow calculations during compile time. They maybe did not generate code and they will not result in any class and also not in an instance. The complete code is evaluated during compile time and results in new types which itself can be used as traits for other templates or they can calculate constants which can be used as normal values in the code. All this without any template->class->object relation.
And this is the place where sometimes integer values come in use. They can be used to do compile time calculations. And also this values can be used as traits for selecting specialization.
So simply your rule is only one facet of the c++ template world. And also in this little world, an integer can be used to create classes with this int parameters, like fixed sized arrays and others. See std::array for example where a int value for the size is a template parameter.
Another use case for int parameters in templates are recursive templates which runs over types. In this case often a counting int parameter can be used. Maybe this will be evaluated like a switch in compile time and the counter in compile time is something like an enum in the run time world.
Hope this helps.
Your question is confusing. You claim to ask:
why would I want to use a type parameter template?
However your example is an example of using a non-type template parameter.
You would want/need to use a non-type template parameter (as in your example) when the value-in-question must be a compile time constant.
For example, the second template parameter of std::array affects its size, which must be a compile time constant, and therefore can only be affected by compile time constants. Therefore you cannot specify this at run time, and therefore it must be specified via template parameter at compile time.
You can see an example here:
https://android.googlesource.com/platform/art/+/master/compiler/utils/arena_allocator.h
ArenaAllocatorStatsImpl is defined as (line 63):
template class ArenaAllocatorStatsImpl;
where kCount means that you want to count allocations if it's true.
Then you have an implementation (line 66) of version which doesn't count allocations
template <> class ArenaAllocatorStatsImpl
In line 82 there is a generic implementation but it's used only for the case where kCount is true because false is covered by implementation in line 66.
This allows you to have two version of code. One for debugging and developing and other for production. Templates are resolved at compile time so you have no overhead on production.
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.
I need to bind a simple template method to LUA, something like
void addComponent<T>(IComponent*);
I'm using tolua to do the bindings but it doesn't support class/method templates (tolua++ supports class templates but not the method ones :) ). Is there any way to bind this method manually?
Thanks in advance.
C++ templates do not actually exist outside of the compiler. Instantiations of templates exist, but the templates themselves are purely a compile-time construct.
There is no function called void addComponent<T>(IComponent*); There is a function called, void addComponent<int>(IComponent*) or void addComponent<float>(IComponent*) or for any particular type you want. But templates are not real functions.
You can bind an instantiation of a template, which is a concrete function. This works just like binding any free function in toLua. The name of an instantiation would be, addComponent<TypeName> where TypeName is the name of the concrete type you want to instantiate it with.
To put it another way, you can't bind the concept of addComponent which is defined for any type. You can bind any actual addComponent that is defined for a specific type.
I have a class that is defined as the following:
template <class WidgetType>
class CometWidget : public WidgetType;
Inside a function I am doing this:
dynamic_cast<CometWidget *>(iter2->second.second)->changesCommited_();
and it resolves the CometWidget type, complies and run correctly.
The code runs inside the CometWidget class.
How on earth does this happen?
Why is that so? Should it even compile?
If it's inside the declaration of CometWidget then you don't need to explicitly qualify the template (or whatever term you use to say CometWidget<...>).
Very interesting indeed. It seems to me like an interesting compiler bug.
It is possible to deduce the correct argument of the CometWidget<> template - just the same way you can deduce template parameters of a function from argument list. If it would be static cast, it would be less surprising.
With dynamic cast, there's little expected to be in common between the source and the target type. So, such "guessing" might have occurred, but then it's not a rightful one.
What compiler is this?