GNU/Linux:
cmake -S . -B build && cmake --build build && ./dat_triple
Windows:
cmake -S . -B build_win -G Ninja && cmake --build build_win && .\dat_triple
| template <typename T, typename U, typename V> | |
| class func_type_triple { | |
| public: | |
| using type_a = T; | |
| using type_b = U; | |
| using type_c = V; | |
| }; | |
| using dat_triple = func_type_triple<int, double, char>; |
| # ignore build directories and generated runtime artifacts | |
| build | |
| build_win | |
| dat_triple | |
| *.exe | |
| *.ilk | |
| *.pdb |
GNU/Linux:
cmake -S . -B build && cmake --build build && ./dat_triple
Windows:
cmake -S . -B build_win -G Ninja && cmake --build build_win && .\dat_triple
| cmake_minimum_required(VERSION 3.16) | |
| project( | |
| dat_triple | |
| VERSION 0.1.0 | |
| DESCRIPTION "A little bit of typename silliness." | |
| HOMEPAGE_URL | |
| https://gist.github.com/phetdam/8ce39b26e067a426f13722b94b019a47 | |
| LANGUAGES CXX | |
| ) | |
| set(CMAKE_CXX_STANDARD 17) | |
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
| add_executable(dat_triple dat_triple.cc) | |
| set_property( | |
| TARGET dat_triple | |
| PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR} | |
| ) |
| /** | |
| * @file dat_triple.cc | |
| * @author Derek Huang | |
| * @brief A little bit of typename silliness. | |
| * @copyright MIT License | |
| */ | |
| #include <cstdlib> | |
| #include <iostream> | |
| namespace { | |
| /** | |
| * A class with using-defs to its types. | |
| */ | |
| template <typename T, typename U, typename V> | |
| class func_type_triple { | |
| public: | |
| using type_a = T; | |
| using type_b = U; | |
| using type_c = V; | |
| }; | |
| using dat_triple = func_type_triple<int, double, char>; | |
| template <typename T> | |
| void tprint() | |
| { | |
| std::cout << "a T" << std::endl; | |
| } | |
| template <> | |
| void tprint<int>() | |
| { | |
| std::cout << "an int" << std::endl; | |
| } | |
| template <> | |
| void tprint<double>() | |
| { | |
| std::cout << "a double" << std::endl; | |
| } | |
| template <> | |
| void tprint<char>() | |
| { | |
| std::cout << "a char" << std::endl; | |
| } | |
| /** | |
| * Invoke `tprint` specializations given a `func_type_triple<T, U, V>`. | |
| * | |
| * @tparam Tr `func_type_triple<T, U, V>` | |
| * | |
| * @param t `const Tr&` to infer types from | |
| */ | |
| template <typename Tr> | |
| void triple_tprint(const Tr& t) | |
| { | |
| tprint<typename Tr::type_a>(); | |
| tprint<typename Tr::type_b>(); | |
| tprint<typename Tr::type_c>(); | |
| } | |
| } // namespace | |
| int main() | |
| { | |
| triple_tprint(dat_triple()); | |
| return EXIT_SUCCESS; | |
| } |