微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std::array 实现上隐式构造函数的奇怪错误

如何解决std::array 实现上隐式构造函数的奇怪错误

#include "array.hpp"

int main() {
    constexpr array<int,5> a1 = { { 2,4,6,8 } };
}

这是我的代码^

我查了一下,据说隐式构造函数可以像这样执行 { { blah,blah,blah } } ,但仍然不起作用。我也只是做了一个统一的大括号初始化语法(a1 = { 2,8 }),但没有奏效。

错误

main.cpp: In function ‘int main()’:
main.cpp:5:57: error: Could not convert ‘{{2,8}}’ from ‘<brace-enclosed initializer list>’ to ‘const xstl::array<int,5>’
    5 |     constexpr xstl::array<int,8 } };
      |                                                         ^
      |                                                         |
      |                                                         <brace-enclosed initializer list>
main.cpp:6:57: error: Could not convert ‘{{1,3,5,7}}’ from ‘<brace-enclosed initializer list>’ to ‘const xstl::array<int,5>’
    6 |     constexpr xstl::array<int,5> a2 = { { 1,7 } };
      |                                                         ^
      |                                                         |
      |                                                         <brace-enclosed initializer list>

我不明白错误,因为构造函数是隐式的?

为什么这个聚合错误?为什么 std::array 实现有效而此实现无效?

这里是实现,不要太多:

#ifndef HEADER_ARRAY_HPP
#define HEADER_ARRAY_HPP

#include <cstddef>
#include <iterator>
#include <stdexcept>

template <class T,std::size_t N>
struct array {
    using value_type = T;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using reference = value_type&;
    using const_reference = const value_type&;
    using pointer = value_type*;
    using const_pointer = const value_type*;
    using iterator = value_type*;
    using const_iterator = const value_type*;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    const_reference at(size_type pos) const {
        return pos < size() ? Data[pos] : throw std::out_of_range("");
    }

    const_reference operator[](size_type pos) const {
        return Data[pos];
    }

    reference front() {
        return *begin();
    }

    const_reference front() const {
        return *begin();
    }

    reference back() {
        return *std::prev(end());
    }

    const_reference back() const {
        return *std::prev(end());
    }

    T *data() noexcept {
        return Data;
    }

    const T *data() const noexcept {
        return Data;
    }

    iterator begin() noexcept {
        return Data;
    }

    const_iterator begin() const noexcept {
        return Data;
    }

    const_iterator cbegin() const noexcept {
        return Data;
    }

    iterator end() noexcept {
        return Data + size();
    }

    const_iterator end() const noexcept {
        return Data + size();
    }

    const_iterator cend() const noexcept {
        return Data + size();
    }

    reverse_iterator rbegin() noexcept {
        return reverse_iterator(end());
    }

    const_reverse_iterator rbegin() const noexcept {
        return const_reverse_iterator(end());
    }

    const_reverse_iterator crbegin() const noexcept {
        return const_reverse_iterator(end());
    }

    reverse_iterator rend() noexcept {
        return reverse_iterator(begin());
    }

    const_reverse_iterator rend() const noexcept {
        return const_reverse_iterator(begin());
    }

    const_reverse_iterator crend() const noexcept {
        return const_reverse_iterator(begin());
    }

    constexpr bool empty() const noexcept {
        return begin() == end();
    }

    constexpr size_type size() const noexcept {
        return N;
    }

    constexpr size_type max_size() const noexcept {
        return N;
    }

    void fill(const T& value) {
        size_type i = 0;

        for (; i < size(); i++) {
            Data[i] = value;
        }
    }

    void swap(array& other) noexcept {
        size_type i;

        for (i = 0; i < other.size(); i++) {
            other.Data[i] = Data[i];
        }

        for (i = 0; i < size(); i++) {
            Data[i] = other.Data[i];
        }
    }

private:
    T Data[N];
};

#endif // HEADER_ARRAY_HPP

解决方法

std::array 是一个聚合,具有隐式声明的构造函数,它按照 aggregate initialization 的规则初始化数组。聚合条件之一是,聚合没有私有或受保护的直接非静态数据成员。

您所期望的封闭数组的聚合初始化是不可能的,因为 Data 是私有的。将 data 设为公共类成员,您就可以使示例正常工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。