Metafunctions¶
Type Metafunctions¶
For example, the metafunction Iterator is a type metafunction, i.e. it is used to determine a type. Type metafunctions have the form:
typename TypeMetaFunc<T1, T2, ..., TN>::Type
TypeMetaFunc
- The name of the metafunction
T1, T2, ..., TN
- Arguments (types or constants)
Type
- The resulting type
The keyword typename
must be stated if one of the arguments T1, T2, ..., TN
is or uses a template parameter.
For example the following piece of code uses the metafunction Iterator
to determine an iterator type for a string class:
String<char> str = "I am a string";
Iterator<String<char> >::Type it = begin(str);
while (! atEnd(it, str))
{
std::cout << *it;
++it;
}
std::cout << std::endl;
I am a string
Value Metafunctions¶
Metafunctions can also be used to determine constant values at compile time. The general form of value metafunctions is:
VALUE_META_FUNC<T1, T2, ..., TN>::VALUE
VALUE_META_FUNC
- The name of the metafunction
T1, T2, ..., TN
- Arguments (types or constants)
VALUE
- The resulting constant value
For example the following function prints the length of a fixed sized string using the value metafunction LENGTH:
template <typename T>
void printLenOfFixedSizeString(T const &)
{
std::cout << LENGTH<T>::VALUE << std::endl;
}
int main()
{
String<char, Array<100> > my_str;
printLenOfFixedSizeString(my_str);
return 0;
}
100
Important
Different uses of “Value”:
Please note that Value (Value<TSomeType>::Type
) is a Type Metafunction, because it returns a Type (e.g. of values in a container) and not a value.
Assignment 1¶
- Objective
- Write a generic function
checkContainerForDna(T & container)
that prints out a message if the value inside the container is of the type Dna. The typeT
of the container should be specified as a template argument. Test you function with some examples. - Hint
- Use the Type Metafunction Value to access the (alphabet-)type of the elements in the container.
- Use the Value Metafunction IsSameType to check for type equality.
- Solution
Your program should look something like this:
#include <iostream> #include <seqan/basic.h> #include <seqan/stream.h> using namespace seqan; template <typename T> void checkContainerForDna(T & container) { // Type Metafunction Value<> typedef typename Value<T>::Type TAlphType; // Value Metafunction IsSameType<> evaluated at compile time if (IsSameType<TAlphType, Dna>::VALUE) std::cout << "I have found a container with Dna!" << std::endl; else std::cout << "No Dna anywhere." << std::endl; } int main() { typedef String<Dna> TDnaString; TDnaString dna = "AAAATTTT"; typedef String<int> TIntString; TIntString numbers; appendValue(numbers, 1); appendValue(numbers, 3); checkContainerForDna(dna); checkContainerForDna(numbers); return 0; }
Note: Because the Value Metafunction
IsSameType<>
is evaluated at compile time, the part of the if-statement code that does not apply won’t even appear in the compiled code. This can be an improvement to the runtime of your code.The output is the following:
I have found a container with Dna! No Dna anywhere.