| Metafunctions Metafunctions are used for getting types and constants at compile time. Contents 1 Motivation 2 Type Metafunctions 3 Value Metafunctions
1 Motivation Generic algorithms usually have to know certain types that correspond to their arguments: An algorithm on strings may need to know which type of characters are stored in the string, or what kind of iterator can be used to browse it. SeqAn uses Metafunctions (also known as "traits") for that purpose. For example: Assuming that we define a string of amino acids: String<AminoAcid> str = "ARN"; Now lets define a function that exchanges the first two values in a string: void exchangeFirstValues(String<AminoAcid> & str) { if (length(str) < 2) return; AminoAcid temp = str[0]; str[0] = str[1]; str[1] = temp; } Since this function only works for instances of String<AminoAcid>, we could try to make it more general by making a template out of it: template <typename T> void exchangeFirstValues(T & str) { if (length(str) < 2) return; AminoAcid temp = str[0]; str[0] = str[1]; str[1] = temp; } Now the function works for all sequence types T that store AminoAcid objects, but it will fail for other value types as soon as the variable temp cannot store str[0] anymore. To overcome this problem, we must redefine temp in a way that it can store a value of the correct type. The question is: "Given a arbitrary type T, what is the value type of T?" The metafunction Value anwers this question: "The value type of T is given by Value<T>::Type." Hence, the final version of our function exchangeFirstValues reads as follows: template <typename T> void exchangeFirstValues(T & str) { if (length(str) < 2) return; typename Value<T>::Type temp = str[0]; str[0] = str[1]; str[1] = temp; } We can view Value as a kind of "function" that takes T as an argument (in angle brackets) and returns the required value type of T. In fact, Value is not implemented as a C++ function, but as a class template. This class template is specialized for each sequence type T in a way that the typedef Type provides the value type of T. Unfortunately, the current C++ language standard does not allow to write simply "Value<T> temp;", so we must select the return value by appending "::Type". The leading "typename" becomes necessary since Value<T>::Type is a type that depends on a template parameter of the surrounding function template. 2 Type Metafunctions The metafunction Value 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. 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; } 3 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
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; } String<char, Array<100> > my_str; printLenOfFixedSizeString(my_str); 100 SeqAn - Sequence Analysis Library - www.seqan.de