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 seqan2; 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.