C++ C++;数组包装器

C++ C++;数组包装器,c++,arrays,templates,C++,Arrays,Templates,我希望在数组周围有一个包装器,例如,它将存储在堆栈中—不关心内存释放—可以通过大括号列表进行初始化,并且可能可以在普通数组的任何位置进行替换。然后,我生成了以下代码。现在我想知道,我错过了什么吗那么,这是我想要的吗 模板 结构数组 { T体[大小]; 运算符T*(){返回体;} }; 编辑: 我可能不准确。包装材料仅用于施工目的。当处于初始化列表(主要是)中时,它应用于从大括号列表构造数组。像 A类{ 受保护:A(整数数组[]) ... B类:公共A{ 公众:B(): A((数组){{1,2}

我希望在数组周围有一个包装器,例如,它将存储在堆栈中—不关心内存释放—可以通过大括号列表进行初始化,并且可能可以在普通数组的任何位置进行替换。然后,我生成了以下代码。现在我想知道,我错过了什么吗那么,这是我想要的吗

模板
结构数组
{
T体[大小];
运算符T*(){返回体;}
};
编辑:

我可能不准确。包装材料仅用于施工目的。当处于初始化列表(主要是)中时,它应用于从大括号列表构造数组。像

A类{
受保护:A(整数数组[])
...
B类:公共A{
公众:B():
A((数组){{1,2}})
...

有一个建议是使用
const
版本的casting操作符。-我一直在考虑这一点,但不确定是否真的需要它。当使用
const T[]
是通过现有运算符隐式完成的,常数数组可以通过给定
T=const…
来定义,还有原因吗?

对于一个基本示例,我认为除了一些辅助函数之外,没有什么可以改进的地方。特别是,如果有一个返回大小的方法,那就更好了:

constexpr std::size_t size() const { return size; }

此外,这里还有其他几个:

  • const
    /non-
    const
    运算符[N]的重载:

    正如@ChristianRau在评论中所述,
    操作符T*
    提供了一个非
    常量版本。我们可以实现
    常量版本如下:

    T const& operator [](std::size_t n) const
    {
        return body[n];
    }
    // similarly for non-const:
    T& operator [](std::size_t n) { return body[n]; }
    
  • begin()
    end()
    定序器(非常有用,例如,对于基于C++11的范围):

  • 一种
    at()
    方法,包括边界检查(与传统的
    运算符[]
    相反):

  • 如果有一个构造函数接受
    std::initializer\u list
    ,这样您就不必使用聚合初始化了,这也很好:

    #include <algorithm>
    #include <initializer_list>
    
    template <typename T, std::size_t N>
    struct Array
    {
        ...
        Array(std::initializer_list<T> const& list)
        {
            std::copy(list.begin(), list.end(), body);
        }
        ...
    };
    
    #包括


    您还可以包括其他功能,但正如我所说的,这是一个基本示例,您最好使用类似的方法。

    对于一个基本示例,我认为除了一些辅助函数之外,您没有什么可以改进的。特别是,如果有一个t返回大小:

    constexpr std::size_t size() const { return size; }
    

    此外,这里还有其他几个:

    • const
      /non-
      const
      运算符[N]
    的重载:

    正如@ChristianRau在评论中所述,
    操作符T*
    提供了一个非
    常量版本。我们可以实现
    常量版本如下:

    T const& operator [](std::size_t n) const
    {
        return body[n];
    }
    // similarly for non-const:
    T& operator [](std::size_t n) { return body[n]; }
    
  • begin()
    end()
    定序器(非常有用,例如,对于基于C++11的范围):

  • 一种
    at()
    方法,包括边界检查(与传统的
    运算符[]
    相反):

  • 如果有一个构造函数接受
    std::initializer\u list
    ,这样您就不必使用聚合初始化了,这也很好:

    #include <algorithm>
    #include <initializer_list>
    
    template <typename T, std::size_t N>
    struct Array
    {
        ...
        Array(std::initializer_list<T> const& list)
        {
            std::copy(list.begin(), list.end(), body);
        }
        ...
    };
    
    #包括


    您还可以包括其他一些功能,但正如我所说的,这是一个基本示例,您最好使用类似的方法。

    您刚才描述的类还应该提供
    常量
    /non-
    常量
    操作符[N]
    @0x499602D2
    []
    应该已经通过转换为指针来处理了,但是关于该转换运算符的另一个
    常量
    版本,这一点很好。您刚才描述了您的类还应该提供
    常量
    /non-
    常量
    重载
    运算符[N]
    @0x499602D2
    []
    应该已经通过转换为指针来处理了,但是关于该转换运算符的另一个
    const
    版本的观点很好。我认为你的第二个注释给出了一个更好的答案。这个问题确实描述了所需的功能。嗯,也许我用的字太大了。包装器不是数组的替代品,而是一个专门用于纯粹用于构造。-不需要羽毛。:)也许您希望从
    at(std::size\u t)const
    返回
    t const&
    ?使用模板参数包的构造函数可能更好,因为它可以使用完美的转发(并且是
    constexpr
    )。对于
    std::array
    我也不理解的是为什么
    size
    不是一个静态成员函数。我认为你的第二条评论给出了一个更好的答案。这个问题确实描述了所需的功能。嗯,也许我用了太多的词。包装器不是数组的替代品,而是一个纯粹用于构造的工具。-Feather不需要。:)也许你想从
    at(std::size\u t)const
    返回
    t const&
    ?我认为带模板参数包的构造函数可能更好,因为它可以使用完美的转发(并且是
    constexpr
    )。我不明白
    std::array
    为什么
    size
    不是静态成员函数。
    template <typename T, std::size_t N>
    struct Array
    {
        ...
        template <typename... Args>
        // possibly constexpr
        Array(Args&&... args) : body{ std::forward<Args>(args)... } 
        {}
        ...
    };