检查类型是否是模板的实例化

R z*_* zu 23 c++ templates auto c++17

我想在编译期间检查类型是否是特定模板的实例化.

例如:

  1. std::vector<int> 实例化 std::vector
  2. std::array<int, 5> 实例化 std::array

我可以进行适用于案例1的测试,但不适用于案例2.

#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <array>
#include <queue>
template<template<typename...> class, typename...>
struct is_instantiation : public std::false_type {};

template<template<typename...> class U, typename... T>
struct is_instantiation<U, U<T...>> : public std::true_type {};

int main() {
    using A = std::vector<int>;
    std::cout << is_instantiation<std::vector, A>::value << "\n";
    std::cout << is_instantiation<std::queue, A>::value << "\n";
    // std::cout << is_instantiation<std::array, A>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)

如何让它适用于这两种情况?

我试过汽车,但无法使它工作.

C++中模板参数中auto的优点17

tan*_*oal 3

专门化的 std::array 大小

我看到的唯一方法是使用预定义的数组大小创建专门的数组类。像这样的东西:

#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <array>
#include <queue>
template<template<typename...> class, typename...>
struct is_instantiation : public std::false_type {};

template<template<typename...> class U, typename... T>
struct is_instantiation<U, U<T...>> : public std::true_type {};

template <class T> class My5Array {
    public:
    My5Array() { }
    private:
    std::array<T, 5> arr;
};

template <class T> class My10Array {
    public:
    My10Array() { }
    private:
    std::array<T, 10> arr;
};

int main() {
    using A = std::vector<int>;
    using B = My5Array<int>;
    std::cout << is_instantiation<std::vector, A>::value << "\n";
    std::cout << is_instantiation<std::queue, A>::value << "\n";
    std::cout << is_instantiation<My5Array, A>::value << "\n";
    std::cout << is_instantiation<My5Array, B>::value << "\n";
    std::cout << is_instantiation<My10Array, B>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)

印刷

1
0
0
1
0
Run Code Online (Sandbox Code Playgroud)

当然,也有缺点:

  • 由于数组大小固定可能会浪费内存
  • 所需数组大小需要多个类
  • 非标准类型 MyXArray 的用法
  • 显然 My5Array 的实例不能同时是 My10Array 的实例(参见上面代码中的 var B)

第一个可能的替代方案:std::dynarray

我还发现了 std::dynarray,它可以代替 std::array 工作,但我认为它尚未包含在最新的 C++ 标准中。也许值得关注。

第二种可能的选择:让它放下

可用的标准容器可能足以满足大多数应用。