(C ++)我的自定义数组无法初始化(编译错误)

时间:2018-07-20 05:41:30

标签: c++ arrays initialization std

我创建了一个继承了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
}

2 个答案:

答案 0 :(得分: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;
}

希望这会有所帮助。

答案 1 :(得分:1)

const handleAsyncActions = async () => { await this.props.loginSuccess({ login: { data: { ...data } } }); await localStorage.setItem('oauth', b64EncodeUnicode(JSON.stringify(data))); await this.props.history.push('/dashboard'); }; handleAsyncActions(); 使用Aggregate Initialization。不幸的是,直到C ++ 17之前,具有基类的类都不能聚合,从而消除了std::array

来自N3291中的 [dcl.init.aggr] (我可以找到最早的C ++ 11标准草案)

  

聚合是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有针对非静态数据成员的大括号或均衡器初始化(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条)和虚拟函数(10.3)。

C ++ 14稍微削弱了这些要求(N4140)

  

集合是没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(条款10),没有虚函数(10.3)。

对基类的限制仍然存在。

当前标准修订版将相关段落重写为

  

聚集是具有

的数组或类(第12条)      

(1.1)-没有用户提供的,显式的或继承的构造函数(15.1),

     

(1.2)-没有私有或受保护的非静态数据成员(第14条),

     

(1.3)-没有虚拟功能(13.3),并且

     

(1.4)-没有虚拟,私有或受保护的基类(13.1)。

哪些允许my_array基类

AltruisticDelay的答案通过public来解决此限制。如果您在选择编译器或标准支持方面受限制,那么这可能是您的正确答案。

如果您可以编译为C ++ 17或更新的标准,则问题中发布的代码将无需修改即可编译。