【问题标题】:Check if a type is instantiation of a template检查类型是否是模板的实例化
【发布时间】:2018-10-21 10:01:42
【问题描述】:

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

例如:

  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";
}

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

我试过自动,但不能让它工作。

Advantages of auto in template parameters in C++17

【问题讨论】:

  • 如果你只对 STL 容器类型感兴趣,你将不得不为数组做一个特殊的案例——据我所知,它是唯一接受非类型模板参数的模板容器。如果您对 any 模板感兴趣,我看不出有什么方法可以使它工作,因为类型和非类型模板没有通用语法。

标签: c++ templates c++17 auto


【解决方案1】:

特殊化 std::array 大小

我看到的唯一方法是制作具有预定义数组大小的专用 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";
}

打印

1
0
0
1
0

当然也有缺点:

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

第一种可能的选择:std::dynarray

​​>

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2014-04-30
    相关资源
    最近更新 更多