【问题标题】:Create alias for numeric array为数值数组创建别名
【发布时间】:2016-09-16 07:29:45
【问题描述】:

我想创建一个只有数字类型的 std::array 别名

template<typename T, std::size_t n, T = std::is_arithmetic<T>::value>
using NumericArray = std::array<T, n>;

这适用于整数

NumericArray<int, 2> i{1, 2};

但是如果我想要一个浮点数或双精度数,我会因为非类型模板参数而出错

NumericArray<float, 2> f{1.0f, 2.0f};

还有其他方法可以做到这一点吗?

【问题讨论】:

    标签: c++ c++11 c++14


    【解决方案1】:

    如果您想阻止某人将此别名用于非算术类型,那么您做错了。

    您的代码将允许任何作为有效模板参数的类型,并且可以从 bool 构造,仅此而已。

    正确的解决方案是这样的:

    template <typename T, std::size_t n>
    using NumericArray = std::enable_if_t<std::is_arithmetic<T>::value, std::array<T, n>>;
    

    为什么您的代码不起作用:

    看这部分:

    template<typename T, std::size_t n, T = std::is_arithmetic<T>::value>
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    它创建一个类型为 T 的未命名模板参数并为其设置默认值。

    即使std::is_arithmetic&lt;T&gt;::value 为假,只要T 可以从bool 构造,代码就会编译。

    当然,T 也必须可以用作模板参数。 (这就是float 不起作用的原因。浮点类型不能是模板参数。请参阅:Why can't I use float value as a template parameter?

    同样,如果std::is_arithmetic&lt;T&gt;::value 为假,编译器就没有理由生成任何错误。

    例如,您的代码将允许以下类型:

    struct S
    {
        constexpr S(bool) {}
    };
    

    【讨论】:

    • 很好地解释了为什么它不起作用。我认为这是我们可以给 OP 的最重要的想法。不仅仅是解决方案。 +1
    【解决方案2】:

    (希望)很快我们将能够使用概念非常干净地编写它:

    template <class T>
    concept constexpr bool Arithmetic = std::is_arithmetic_v<T>;
    
    template <Arithmetic T, std::size_t n>
    using NumericArray = std::array<T, n>;
    

    顺便说一句,这现在在 gcc 7 上使用-fconcepts 编译和运行。对于 gcc 6,您需要使用 std::is_arithmetic&lt;T&gt;::value


    在 c++14 中你也有一些方法。

    我更喜欢:

    template <class T, std::size_t n,
              class Enable = std::enable_if_t<std::is_arithmetic<T>::value>>
    using NumericArray = std::array<T, n>;
    

    @holyblackcathis answer给了你另一种方式

    【讨论】:

    • Concepts 是一个 TS,不同于 C++17。这位在 3 月份参加委员会会议的人表示,Concepts TS 尚未被投票通过 C++17。 honermann.net/blog/?p=3 从那以后有什么我没听说过的变化吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2016-10-15
    相关资源
    最近更新 更多