Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Template metaprogramming
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Concepts== The C++20 standard brought C++ programmers a new tool for meta template programming, concepts.<ref>{{Cite web|url=https://en.cppreference.com/w/cpp/language/constraints|title=Constraints and concepts (since C++20) - cppreference.com|website=en.cppreference.com}}</ref> [[Concepts (C++)|Concepts]] allow programmers to specify requirements for the type, to make instantiation of template possible. The compiler looks for a template with the concept that has the highest requirements. Here is an example of the famous [[Fizz buzz]] problem solved with Template Meta Programming. <syntaxhighlight lang="cpp"> #include <boost/type_index.hpp> // for pretty printing of types #include <iostream> #include <tuple> /** * Type representation of words to print */ struct Fizz {}; struct Buzz {}; struct FizzBuzz {}; template<size_t _N> struct number { constexpr static size_t N = _N; }; /** * Concepts used to define condition for specializations */ template<typename Any> concept has_N = requires{ requires Any::N - Any::N == 0; }; template<typename A> concept fizz_c = has_N<A> && requires{ requires A::N % 3 == 0; }; template<typename A> concept buzz_c = has_N<A> && requires{ requires A::N % 5 == 0;}; template<typename A> concept fizzbuzz_c = fizz_c<A> && buzz_c<A>; /** * By specializing `res` structure, with concepts requirements, proper instantiation is performed */ template<typename X> struct res; template<fizzbuzz_c X> struct res<X> { using result = FizzBuzz; }; template<fizz_c X> struct res<X> { using result = Fizz; }; template<buzz_c X> struct res<X> { using result = Buzz; }; template<has_N X> struct res<X> { using result = X; }; /** * Predeclaration of concatenator */ template <size_t cnt, typename... Args> struct concatenator; /** * Recursive way of concatenating next types */ template <size_t cnt, typename ... Args> struct concatenator<cnt, std::tuple<Args...>> { using type = typename concatenator<cnt - 1, std::tuple< typename res< number<cnt> >::result, Args... >>::type;}; /** * Base case */ template <typename... Args> struct concatenator<0, std::tuple<Args...>> { using type = std::tuple<Args...>;}; /** * Final result getter */ template<size_t Amount> using fizz_buzz_full_template = typename concatenator<Amount - 1, std::tuple<typename res<number<Amount>>::result>>::type; int main() { // printing result with boost, so it's clear std::cout << boost::typeindex::type_id<fizz_buzz_full_template<100>>().pretty_name() << std::endl; /* Result: std::tuple<number<1ul>, number<2ul>, Fizz, number<4ul>, Buzz, Fizz, number<7ul>, number<8ul>, Fizz, Buzz, number<11ul>, Fizz, number<13ul>, number<14ul>, FizzBuzz, number<16ul>, number<17ul>, Fizz, number<19ul>, Buzz, Fizz, number<22ul>, number<23ul>, Fizz, Buzz, number<26ul>, Fizz, number<28ul>, number<29ul>, FizzBuzz, number<31ul>, number<32ul>, Fizz, number<34ul>, Buzz, Fizz, number<37ul>, number<38ul>, Fizz, Buzz, number<41ul>, Fizz, number<43ul>, number<44ul>, FizzBuzz, number<46ul>, number<47ul>, Fizz, number<49ul>, Buzz, Fizz, number<52ul>, number<53ul>, Fizz, Buzz, number<56ul>, Fizz, number<58ul>, number<59ul>, FizzBuzz, number<61ul>, number<62ul>, Fizz, number<64ul>, Buzz, Fizz, number<67ul>, number<68ul>, Fizz, Buzz, number<71ul>, Fizz, number<73ul>, number<74ul>, FizzBuzz, number<76ul>, number<77ul>, Fizz, number<79ul>, Buzz, Fizz, number<82ul>, number<83ul>, Fizz, Buzz, number<86ul>, Fizz, number<88ul>, number<89ul>, FizzBuzz, number<91ul>, number<92ul>, Fizz, number<94ul>, Buzz, Fizz, number<97ul>, number<98ul>, Fizz, Buzz> */ } </syntaxhighlight>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)