我试图检测一个类型(或者更准确地说,一个标识符作为技术模板不是一个类型)是否是一个模板,例如有一个函数 isTemplate
,它的行为方式如下:
template <typename T>
struct X;
struct Y;
template <int N>
struct Z;
isTemplate<X>(); // Should return true
isTemplate<Y>(); // Should return false
isTemplate<Z>(); // Should return true. This one is especially tricky to get the correct results.
如何实现 isTemplate
函数?
注意:我尝试了以下简单的实现:
template <typename T> // If T is a simple type this overload will be selected
consteval bool isTemplate(int) {
return false;
}
template <template <class...> class T> // This overload will be selected if T is a template and fits in as a template template parameter
consteval bool isTemplate(char) { // Dummy char parameter to avoid redefinition
return true;
}
但是当它需要检测带有非类型参数的模板时它不起作用。
答案 0 :(得分:4)
将 YSC's Answer 扩展到 another related question,您可以添加一个函数重载,该函数重载使用 auto...
非类型模板参数的参数包来检测接受非类型参数的模板。>
#include <iostream>
#include <type_traits>
struct foo {};
template<typename T> struct bar {};
template<int I> struct baz {};
template<template<class ...> class T>
constexpr bool is_template() { return true; }
// ADDITIONAL SPECIALIZATION for non-type arguments
template<template<auto ...> class T>
constexpr bool is_template() { return true; }
template<class T>
constexpr bool is_template() { return false; }
int main() {
std::cout << is_template<foo>() << '\n'; // 0
std::cout << is_template<bar>() << '\n'; // 1
std::cout << is_template<baz>() << '\n'; // 1
}
据我所知,目前没有办法定义一个同时接受类型和非类型模板参数的参数包。实际上,这可能意味着必须为 std::array
之类的东西编写特殊情况。