繁体   English   中英

检查类是否是模板特化

[英]Check if class is a template specialization

我想检查一个类是否是另一个类的模板特化。 我尝试过的是:

template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

当所有模板参数都是类型参数时它工作得很好,但当一些是非类型参数时就不行了 例如,它适用于std::vector但不适用于std::array (因为后者接受非类型参数std::size_t )。

在编译时进行检查很重要。 此外,该解决方案必须适用于任何模板,而不仅仅是向量或数组。 这意味着它可以是任意数量的类型参数和任意数量的非类型参数。 例如它应该使用template <class A, bool B, class C, int D, class... Args> class foo;

C++20 是一个奇怪的、奇怪的世界。 欢迎交叉检查,因为我是 CTAD 的初学者,并不完全确定我已经涵盖了所有基础。

该解决方案使用 SFINAE 来检查所请求的类模板和神秘类型之间的类模板参数推导 (CTAD) 是否成功。 执行额外的is_same检查以防止不需要的转换。

template <auto f>
struct is_specialization_of {
private:
    template <class T>
    static auto value_impl(int) -> std::is_same<T, decltype(f.template operator()<T>())>;

    template <class T>
    static auto value_impl(...) -> std::false_type;

public:
    template <class T>
    static constexpr bool value = decltype(value_impl<T>(0))::value;
};

// To replace std::declval which yields T&&
template <class T>
T declrval();

#define is_specialization_of(...) \
    is_specialization_of<[]<class T>() -> decltype(__VA_ARGS__(declrval<T>())) { }>::value

// Usage
static_assert(is_specialization_of(std::array)<std::array<int, 4>>);

第一个警告:由于我们不能在不知道参数的情况下以任何方式为类模板声明参数,因此只能通过跳过一些箍来将其传递到将执行 CTAD 的位置。 C++20 constexpr 和模板友好的 lambda 在这里有很大帮助,但语法很复杂,因此有帮助宏。

第二个警告:这只适用于可移动类型,因为 CTAD 仅适用于对象声明,而不适用于引用声明。 也许未来的提案将允许诸如std::array &arr = t;东西std::array &arr = t; ,然后这将被修复!

实际上是通过记住 C++17 保证复制省略来修复的,它允许从不可移动的右值直接初始化,就像这里的情况一样!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM