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; }
此外,这里还有其他几个:
/non-const
运算符[N]的重载: 正如@ChristianRau在评论中所述,const
提供了一个非操作符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()
定序器(非常有用,例如,对于基于C++11的范围):end()
- 一种
方法,包括边界检查(与传统的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); } ... };
的重载: 正如@ChristianRau在评论中所述,#包括
您还可以包括其他功能,但正如我所说的,这是一个基本示例,您最好使用类似的方法。对于一个基本示例,我认为除了一些辅助函数之外,您没有什么可以改进的。特别是,如果有一个t返回大小:constexpr std::size_t size() const { return size; }
此外,这里还有其他几个:
/non-const
运算符[N]const
提供了一个非操作符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()
定序器(非常有用,例如,对于基于C++11的范围):end()
- 一种
方法,包括边界检查(与传统的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); } ... };
@0x499602D2#包括
您还可以包括其他一些功能,但正如我所说的,这是一个基本示例,您最好使用类似的方法。您刚才描述的类还应该提供
/non-常量
操作符[N]常量
应该已经通过转换为指针来处理了,但是关于该转换运算符的另一个[]
版本,这一点很好。您刚才描述了您的类还应该提供常量
/non-常量
重载常量
@0x499602D2运算符[N]
应该已经通过转换为指针来处理了,但是关于该转换运算符的另一个[]
版本的观点很好。我认为你的第二个注释给出了一个更好的答案。这个问题确实描述了所需的功能。嗯,也许我用的字太大了。包装器不是数组的替代品,而是一个专门用于纯粹用于构造。-不需要羽毛。:)也许您希望从const
返回at(std::size\u t)const
?使用模板参数包的构造函数可能更好,因为它可以使用完美的转发(并且是t const&
)。对于constexpr
我也不理解的是为什么std::array
不是一个静态成员函数。我认为你的第二条评论给出了一个更好的答案。这个问题确实描述了所需的功能。嗯,也许我用了太多的词。包装器不是数组的替代品,而是一个纯粹用于构造的工具。-Feather不需要。:)也许你想从size
返回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)... } {} ... };