【问题标题】:C++ Template Type Traits IssueC++ 模板类型特征问题
【发布时间】:2018-01-15 01:47:35
【问题描述】:

我是创建自己的类型特征的新手,我想创建一个类型特征,让我能够识别传递的类型是否是预期的容器。

template<typename T, typename ... Types>
struct is_array
{
    static constexpr bool value = false;
};

template<typename ... Types>
struct is_array<std::array<Types...>>
{
    static constexpr bool value = true;
};

我采用了上述格式,它适用于除数组以外的所有容器类型:

constexpr bool state = is_array<std::array<int, 5>>::value;

当它应该为真时,上面的计算结果为假。这只发生在数组类中,我相信这是因为它有 2 个没有默认值的模板参数。我无法解决这个问题。

【问题讨论】:

  • std::array 的实际特化永远不会匹配std::array&lt;Types...&gt;,因为它有一个非类型模板参数。你想要template&lt;typename T, size_t N&gt; struct is_array&lt;std::array&lt;T, N&gt;&gt; { ... };
  • 在您的示例中,5 不是类型,因此与 Types... 不匹配。
  • 更令人困惑的是,有一个std::is_array trait 专门std::array 检测为一个数组。
  • 所以is_std_array 会是一个更好的名字。

标签: c++ templates metaprogramming template-meta-programming typetraits


【解决方案1】:

首先,你的 trait 应该只有一个模板参数:预期的数组类型:

template<typename T/*, typename ... Types*/>
struct is_array {
    static constexpr bool value = false;
};

第二,std::array定义为:

template<
    class T,
    std::size_t N
> struct array;

作为第一个类型参数 T 和类型为 std::size_t 的非类型参数 N

因此,您的真正专业应该是:

template<typename T, std::size_t N>
struct is_array<std::array<T,N>>
{
    static constexpr bool value = true;
};

注意,不是定义成员value,我们更喜欢从std::true_type and std::false_type 继承,它提供了一些其他成员别名+转换运算符。那么代码就变成了:

template<typename T>
struct is_array : std::false_type {};

template<typename T, std::size_t N>
struct is_array<std::array<T,N>> : std::true_type {};

【讨论】:

  • 这太棒了,完美运行。感谢您向我展示了正确的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 2011-09-08
相关资源
最近更新 更多