I would like to define a function that prints the typeid names of types in its template parameter list. The function accepts no value parameters. So for example calling print<int>()
should print int
, print<int, double>()
should print int, double
and calling print<>()
should output the string no types
.
I have a solution that works, however it uses an extra vector
to do this, suggested by this answer:
#include <iostream>
#include <vector>
template<class... T>
void print() {
std::vector<const char*> ids{ typeid(T).name()... };
if (ids.empty()) {
std::cout << "no types\n";
return;
}
const auto last = ids.size() - 1;
for (size_t i = 0; i < last; i++)
std::cout << ids[i] << ", ";
std::cout << ids[last] << '\n';
}
int main() {
print<>();
print<int, double, char>();
return 0;
}
As you can see, this function isn't very compile-time friendly. I tried to create a version of the code that doesn't involve a vector, however there is a different problem.
#include <iostream>
template<typename... Types>
void print() {
((std::cout << typeid(Types).name() << ", "), ...);
}
template<>
void print() {
std::cout << "no types\n";
}
int main() {
print<>();
print<int, double, char>();
return 0;
}
Output
no types
int, double, char,
This version is printing a comma after the last type in the template parameter list. I would like to get rid of this comma.
To have the comma only appear before the type but not after it you could print the first type, then print everything else with the comma before the type.
Note that only msvc prints
int
, both clang and gcc usei
for int, see typeid.If you want the approach with the loop, then you can replace the vector with a std::array which does no heap allocations in the assembly.