Sign in to follow this  

Metaprogramming with Templates (question)

This topic is 3149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

From explanations of metaprogramming with templates (in C++), there's still something that I wasn't sure about. Are templates limited to creating classes at compile-time, or any time (dynamically)? For example, what if I wanted my program to run for a while, and with changing conditions, create a new class from the template with a different type. A more concrete example: Let's say you have a template that contains a generic search algorithm somewhere in it and you don't know beforehand what type will be best suited for the future tasks. While running, you may want this template to generate a new class (not originally planned for) if a different search algorithm is preferable. Is this feasible, or must I recompile the project? Thank you.

Share this post


Link to post
Share on other sites
Template or not, you can never create a new class in C++ at run time baring some special code that calls the compiler or some such. Also I don't really understand your example. It sounds more like something that is done with straight virtuals but I can't be sure. What exactly are you trying to do?

Share this post


Link to post
Share on other sites
Most probably: To expand your C++ program in future, without the need to completely recompile and redistribute the program, which is related to what is called "plugins", your application needs to be able to bind to shared libraries (a.k.a. DLL's).

Templates are to be evaluated/substituted fully at compile-time (as compared to generics, e.g. in C#), which is a pro and a con of C++ templates. So if you want to use different parameters for your templates in the future, that must happen before compilation.

[Edited by - phresnel on April 29, 2009 4:06:05 AM]

Share this post


Link to post
Share on other sites
Sounds like you are trying to do reflection, but afaik, c++ does not support it.

is this what you are trying to do?
http://en.wikipedia.org/wiki/Reflection_(computer_science)

Share this post


Link to post
Share on other sites
Any programming involving templates is all sorted out at compile time. The main deal about template metaprogramming is you move work from run time to compile time, and thats it really.

Straight up C++ offers little for reflection, but a book on C++/CLI I have makes mention about this ability, though even then it was kinda vague about possible uses (mentions this is the kind of stuff a compiler does).

Share this post


Link to post
Share on other sites
Templated classes give you a way of defining multiple types. This happens at compile time; you cannot invent a new kind of data in the middle of running the program.

If you have a template class Foo<T>, and there is a line of code in your program somewhere that instantiates a Foo<int>, then Foo<int> is a type. Foo&;lt;double>, however, is not, unless you instantiate the template (even though 'double' is a type).

However, it is possible to cause all the Foo<T>s that do exist to be related to each other by inheritance. Say for example that we define Foo<T> to derive from FooBase. This allows you to have a variable of type pointer-to-FooBase, and at runtime, decide exactly what kind of FooBase it points at - where the possibilities are any Foo<T> template instantiation (or the base FooBase itself). Totally useless example:


#include <iostream>
#include <string>

class Printable {
public:
virtual void print(std::ostream& os) const = 0;
~Printable();
};

Printable::~Printable() {}

std::ostream& operator<<(std::ostream& os, const Printable& p) {
p.print(os);
return os;
}

template <typename T>
class PrintableValue : public Printable {
T value;
public:
PrintableValue(const T& value) : value(value) {}
void print(std::ostream& os) const;
};

template <typename T>
void PrintableValue<T>::print(std::ostream& os) const {
os << value;
}

template <typename T>
PrintableValue<T>* make_printable(const T& value) {
return new PrintableValue<T>(value);
}

int main(int argc, char** argv) {
Printable* p;
if (argc < 2) { p = make_printable(42); }
else { p = make_printable(std::string("hi mom")); }
std::cout << *p;
delete p;
}



Here, the template types PrintableValue<int> and PrintableValue<std::string> are implicitly instantiated. The appropriate type is selected, dynamically instantiated, and pointed at by the base class pointer. The operator overload then makes a virtual call to print(), which is selected from the appropriate derived class.

(Note that the template will not work with a string literal, because the constructor would fail to compile: you can't initialize a member from an array. Since you can't assign from an array, either, you'd probably have to specialize the template for array types.)

Share this post


Link to post
Share on other sites

This topic is 3149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this