如何使用初始化列表构造

如何使用初始化列表构造

本文介绍了如何使用初始化列表构造 std::array 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能的重复:
如何使用 initializer_list 初始化成员数组?

你可以用初始化列表构造一个 std::array 就好了:

You can construct an std::array just fine with an initializer list:

std::array<int, 3> a = {1, 2, 3};  // works fine

但是,当我尝试从 std::initializer_list 构造它作为类中的数据成员或基对象时,它不起作用:

However, when I try to construct it from an std::initializer_list as a data member or base object in a class, it doesn't work:

#include <array>
#include <initializer_list>

template <typename T, std::size_t size, typename EnumT>
struct enum_addressable_array : public std::array<T, size>
{
    typedef std::array<T, size> base_t;
    typedef typename base_t::reference reference;
    typedef typename base_t::const_reference const_reference;
    typedef typename base_t::size_type size_type;

    enum_addressable_array(std::initializer_list<T> il) : base_t{il} {}

    reference operator[](EnumT n)
    {
        return base_t::operator[](static_cast<size_type>(n));
    }

    const_reference operator[](EnumT n) const
    {
        return base_t::operator[](static_cast<size_type>(n));
    }
};

enum class E {a, b, c};
enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};

gcc 4.6 的错误:

Errors with gcc 4.6:

test.cpp: In constructor 'enum_addressable_array<T, size, EnumT>::enum_addressable_array(std::initializer_list<T>) [with T = char, unsigned int size = 3u, EnumT = E]':
test.cpp:26:55:   instantiated from here
test.cpp:12:68: error: no matching function for call to 'std::array<char, 3u>::array(<brace-enclosed initializer list>)'
test.cpp:12:68: note: candidates are:
include/c++/4.6.1/array:60:12: note: std::array<char, 3u>::array()
include/c++/4.6.1/array:60:12: note:   candidate expects 0 arguments, 1 provided
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(const std::array<char, 3u>&)
include/c++/4.6.1/array:60:12: note:   no known conversion for argument 1 from 'std::initializer_list<char>' to 'const std::array<char, 3u>&'
include/c++/4.6.1/array:60:12: note: constexpr std::array<char, 3u>::array(std::array<char, 3u>&&)
include/c++/4.6.1/array:60:12: note:   no known conversion for argument 1 from 'std::initializer_list<char>' to 'std::array<char, 3u>&&'

我怎样才能让它工作,以便我的包装类可以使用初始化列表进行初始化,如下所示:

How can I get it to work so that my wrapper class can be initialized with an initializer-list, as such:

enum_addressable_array<char, 3, E> ea = {'a', 'b', 'c'};

推荐答案

std::array<> 没有接受 std::initializer_list<> 的构造函数code>(初始化列表构造函数)并且对于将 std::initializer_list<> 传递给类的构造函数以使其可能工作的含义没有特殊的语言支持.所以失败了.

An std::array<> has no constructor that takes an std::initializer_list<> (initializer list constructor) and there is no special language support for what it may mean to pass a std::initializer_list<> to a class' constructors such that that may work. So that fails.

为了让它工作,你的派生类需要捕获所有元素然后转发它们,一个构造函数模板:

For it to work, your derived class needs to catch all elements and then forward them, a constructor template:

template<typename ...E>
enum_addressable_array(E&&...e) : base_t{{std::forward<E>(e)...}} {}

请注意,在这种情况下您需要 {{...}} 因为大括号省略(在您的情况下省略大括号)在那个地方不起作用.它只允许在 T t = { ... } 形式的声明中使用.因为 std::array<> 由一个嵌入原始数组的结构组成,所以需要两级大括号.不幸的是,我认为 std::array<> 的确切聚合结构未指定,因此您需要希望它适用于大多数实现.

Note that you need {{...}} in this case because brace elision (omitting braces like in your case) does not work at that place. It's only allowed in declarations of the form T t = { ... }. Because an std::array<> consists of a struct embedding a raw array, that will need two level of braces. Unfortunately, I believe that the exact aggregate structure of std::array<> is unspecified, so you will need to hope that it works on most implementations.

这篇关于如何使用初始化列表构造 std::array 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 15:33