打印模板参数列表中类型的 typeid

san*_*ser 1 c++ templates fold-expression c++17

我想定义一个函数,在其模板参数列表中打印类型的 typeid 名称。该函数不接受任何值参数。因此,例如调用print<int>()应该打印intprint<int, double>()应该打印int, double并且调用print<>()应该输出字符串no types

我有一个可行的解决方案,但是它使用了额外的方法来执行此操作,如以下答案vector所示:

#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;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这个函数的编译时不太友好。我尝试创建一个不涉及向量的代码版本,但是存在不同的问题。

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出

no types
int, double, char,
Run Code Online (Sandbox Code Playgroud)

此版本在模板参数列表中的最后一个类型后打印一个逗号。我想去掉这个逗号。

Ahm*_*AEK 6

要让逗号仅出现在类型之前而不是在类型之后,您可以打印第一个类型,然后在类型之前使用逗号打印其他所有内容。

#include <iostream>

template<typename T, typename...Types>
void print_helper() {
    std::cout << typeid(T).name(); // first type
    ((std::cout << ", " << typeid(Types).name()), ...); // everything else
}

template<typename... Types>
void print() {
    print_helper<Types...>();
}

template<>
void print() {
    std::cout << "no types\n";
}

int main() {
    print<>();
    print<int, double, char>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
no types
i, d, c
Run Code Online (Sandbox Code Playgroud)

请注意,只有 msvc 打印int,clang 和 gcc 都使用iint,请参阅typeid

如果您想要使用循环的方法,那么您可以用std::array替换向量,它在程序集中不进行堆分配。

#include <array>
#include <iostream>

template<class... T>
void print() {
    std::array<const char*, sizeof...(T)> 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;
}
Run Code Online (Sandbox Code Playgroud)