Templates
Templates are used to generate different code chunks, functions and classes. Each template starts with the template keyword and sets an identifier and a code chunk, a function or a class, by which this identifier will be replaced when using the template.
The templates should be used instead of the #define preprocessor directive. The main differences from #define are the following:
- The templates support syntax highlighting.
- The templates work relative to a scope (while #define has the global scope).
See Also#
Generating Code Chunks#
A template that is used to generate a code chunk has the following syntax:
template template_name<ARG_NAME> {
code_chunk
}
template print<STRING,DIGIT> {
log.message("%s, ",STRING);
log.message("%d\n",DIGIT);
}
// generate a code chunk
print<typeinfo(12),17>;
print<"12",17>;
// The following code is generated:
// log.message("%s, ","int: 12");
// log.message("%d\n",17);
// log.message("%s, ","12");
// log.message("%d\n",17);
To turn a template argument into a string, use # before the argument:
template print<DIGIT> {
log.message("%d\n",DIGIT);
log.message("text_%s",#DIGIT);
}
print<17>;
// Output:
// 17
// text_17
Generating Functions#
Also it is possible to create a template that generates a function instead of the code chunk. This function will replace the identifier that is set by a template. The syntax of the function template is the following:
template template_name<ARG_NAME> void ARG_NAME {
function_code
}
To declare several functions in one template, simply enclose the functions in curly braces:
template template_name<ARG_NAME> {
void func1_ ## ARG_NAME { function_code; }
void func2_ ## ARG_NAME { function_code; }
}
The following examples demonstrate how to:
- Declare a template with 3 arguments and then generate a function from it:
template sum_template<NAME,A0,A1> void NAME() { log.message("%s\n",typeinfo(A0 + A1)); } // generate the sum() function that adds 1 to 2 sum_template<sum,1,2>; // call the generated function sum(); // Output: int: 3
- Declare several functions in one template and then use this template in the code in order to generate class member functions:
template setget<TYPE,NAME,VALUE> { void set ## NAME(TYPE v) { VALUE = v; } TYPE get ## NAME() { return VALUE; } } class Foo { int a,b,c; // generate the following functions: // void setA(int v) { a = v; } // int getA() { return a; } setget<int,A,a>; // void setB(int v) { b = v; } // int getB() { return b; } setget<int,B,b>; // void setC(string v) { c = v; } // string getC() { return c; } setget<string,C,c>; void info() { log.message("%d %d %s\n",a,b,c); } }; Foo f = new Foo(); // call the generated member functions f.setA(12); f.setB(13); f.setC("Sample string"); f.info(); // Output: 12 13 Sample string
Generating Classes#
The syntax of the template that generates a class is the following:
template template_name<ARG_NAME> {
class ARG_NAME {
class_members
};
}
template my_class<NAME> {
class My ## NAME {
My ## NAME() {
log.message(__FUNC__ + ": called\n");
}
~My ## NAME() {
log.message(__FUNC__ + ": called\n");
}
};
}
// generate the Foo class
my_class<Foo>;
MyFoo f = new MyFoo();
delete f;