(C++) 我的自定义数组无法初始化(编译错误)
Posted
技术标签:
【中文标题】(C++) 我的自定义数组无法初始化(编译错误)【英文标题】:(C++) My custom array cannot be initialized (compile error) 【发布时间】:2018-07-20 05:41:30 【问题描述】:我创建了一个继承 std::array 的自定义数组。 但它不能使用 std::array 的相同语句初始化。 谁能告诉我为什么这不起作用并帮助我正确修改我的代码?
这里是编译错误信息:
main.cpp: In function 'int main()':
main.cpp:32:35: error: no matching function for call to 'my_array::my_array()'
my_array<int, 2> b 1, 2 ; // compile error
^
main.cpp:13:8: note: candidate: my_array::my_array()
struct my_array : std::array<T,N>
^
main.cpp:13:8: note: candidate expects 0 arguments, 1 provided
main.cpp:13:8: note: candidate: constexpr my_array::my_array(const my_array&)
main.cpp:13:8: note: no known conversion for argument 1 from '' to 'const my_array&'
main.cpp:13:8: note: candidate: constexpr my_array::my_array(my_array&&)
main.cpp:13:8: note: no known conversion for argument 1 from '' to 'my_array&&'
下面是我的实现代码。 提前致谢。
#include<iostream>
#include<array>
template<typename T, std::size_t N>
struct my_array : std::array<T,N>
T& operator[](std::size_t n)
if(!(n < N))
std::cout << "out of range" << std::endl;
return (*static_cast<std::array<T,N>*>(this))[n];
const T& operator[](std::size_t n) const
if(!(n < N))
std::cout << "out of range" << std::endl;
return (*static_cast<const std::array<T,N>*>(this))[n];
;
int main(void)
std::array<int, 2> a 1, 2 ; // no error
my_array<int, 2> b 1, 2 ; // compile error
【问题讨论】:
与您的问题无关,但operator[]
函数没有边界检查是有原因的。如果您想要边界检查,请改用at
。
if(n > N) it is out of bound 看起来你在做相反的事情。
很确定你已经违反了在 C++17 之前的编译器中使用基类聚合初始化的规则。试图找到确切的裁决。没有太多机会使用 C++17。
通常,如果有人询问编译错误,必须将它们包含在问题中(通常,它们会准确说明问题所在)。
【参考方案1】:
我会说您的自定义类不知道带有参数 initializer_list 的构造函数,因此您必须自己实现它。
基于您的代码的快速而肮脏的解决方案,但编译和执行:
#include<iostream>
#include<array>
#include <initializer_list>
template<typename T, std::size_t N>
struct my_array : std::array<T,N>
my_array(std::initializer_list<T> list)
int i=0;
for(auto val = list.begin();val != list.end();val++)
std::array<T,N>::at(i++) = *val;
T& operator[](std::size_t n)
if(n < N)
std::cout << "out of range" << std::endl;
return (*static_cast<std::array<T,N>*>(this))[n];
const T& operator[](std::size_t n) const
if(n < N)
std::cout << "out of range" << std::endl;
return (*static_cast<const std::array<T,N>*>(this))[n];
;
int main(void)
std::array<int, 2> a 1, 2 ; // no error
my_array<int, 2> b 1, 2 ; // compile error
std::cout << b.at(0) << ", " << b.at(1) << std::endl;
希望这会有所帮助。
【讨论】:
【参考方案2】:std::array
使用Aggregate Initialization。不幸的是,在 C++17 之前,具有基类的类不能是聚合,这消除了 my_array
。
来自 N3291 中的 [dcl.init.aggr](我有最早的 C++11 后标准草案)
聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数 (12.1),没有用于非静态数据成员 (9.2) 的大括号或均衡器,没有私有或受保护的非静态数据成员(第 11 条),无基类(第 10 条),无虚函数 (10.3)。
C++14 稍微弱化了这些要求(N4140)
聚合是一个数组或类(第 9 条),没有用户提供的构造函数 (12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),并且没有虚函数(10.3)。
对基类的限制仍然存在。
当前标准修订将相关段落改写为
聚合是一个数组或一个类(第 12 条),具有
(1.1) — 没有用户提供的、显式的或继承的构造函数 (15.1),
(1.2) — 没有私有或受保护的非静态数据成员(第 14 条),
(1.3) — 没有虚函数 (13.3),并且
(1.4) — 没有虚拟、私有或受保护的基类 (13.1)。
允许public
基类
AltruisticDelay 的答案通过std::Initializer_list
解决了这个限制。如果您在选择编译器或标准支持方面受到限制,这可能是您的正确答案。
如果您可以编译成 C++17 或更新的标准,则问题中发布的代码无需修改即可编译。
【讨论】:
以上是关于(C++) 我的自定义数组无法初始化(编译错误)的主要内容,如果未能解决你的问题,请参考以下文章
由于 int main() 函数的定义错误,C++ 编译器拒绝了我的代码
急求c语言 dev c++) 利用结构体做一个小系统,为啥直接无法编译运行?