如何构建的std ::数组对象与初始化列表? [英] How to construct std::array object with initializer list?

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

问题描述


  

可能重复:结果
  <一href=\"http://stackoverflow.com/questions/5549524/how-do-i-initialize-a-member-array-with-an-initializer-list\">How我做初始化与initializer_list成员阵列?


您可以构造一个的std ::阵列只是用初始化列表罚款:

 的std ::阵列&LT; INT,3&GT;一个= {1,2,3}; //工作正常

然而,当我尝试从的std :: initializer_list 作为一个类的数据成员或基本对象,这是行不通的构造它:

 的#include&LT;阵列GT;
#包括LT&;&initializer_list GT;模板&LT; typename的T,性病::为size_t大小,类型名EnumT&GT;
结构enum_addressable_array:公众的std ::阵列&LT; T,大小和GT;
{
    的typedef的std ::阵列&LT; T,大小和GT; base_t;
    的typedef typename的base_t ::参考参考;
    的typedef typename的base_t ::为const_reference为const_reference;
    的typedef typename的base_t :: size_type的SIZE_TYPE;    enum_addressable_array(的std :: initializer_list&LT; T&GT; IL):base_t {}金正日{}    参考操作符[](EnumT N)
    {
        返回base_t ::运算符[](的static_cast&LT;&size_type的GT;(N));
    }    运营商为const_reference [](EnumT n)的常量
    {
        返回base_t ::运算符[](的static_cast&LT;&size_type的GT;(N));
    }
};枚举类,E {A,B,C};
enum_addressable_array&LT;焦炭,3,E&GT; EA = {'一','B','C'};

用gcc 4.6错误:

  TEST.CPP:在构造'enum_addressable_array&LT; T,尺寸,EnumT&GT; :: enum_addressable_array(的std :: initializer_list&LT; T&GT;)与T =字符,无符号整型大小= 3U ,EnumT = E]':
TEST.CPP:26:55:从这里实例化
TEST.CPP:12:68:错误:调用没有匹配的函数的std ::阵列&LT;焦炭,3U&GT; ::阵列(小于大括号内的初始化列表&gt;)
TEST.CPP:12:68:注意:考生:
包括/ C ++ / 4.6.1 /数组:60:12:注意:性病::阵列&LT;焦炭,3U&GT; ::阵列()
包括/ C ++ / 4.6.1 /数组:60:12:注意:考生预计0参数,提供了1
包括/ C ++ / 4.6.1 /数组:60:12:注意:constexpr的std ::阵列&LT;焦炭,3U&GT; ::阵列(常量的std ::阵列&LT;焦炭,3U&GT;&安培;)
包括/ C ++ / 4.6.1 /数组:60:12:注意:没有已知的转换参数为从1'的std :: initializer_list&LT;焦炭&GT;'以常量的std ::阵列&LT;焦炭,3U&GT;&放大器;'
包括/ C ++ / 4.6.1 /数组:60:12:注意:constexpr的std ::阵列&LT;焦炭,3U&GT; ::阵列(的std ::阵列&LT;焦炭,3U&GT;&放大器;&安培;)
包括/ C ++ / 4.6.1 /数组:60:12:注意:没有已知的转换参数为从1'的std :: initializer_list&LT;焦炭&GT;'为'的std ::阵列&LT;焦炭,3U&GT;&放大器;&放大器;'

我怎样才能得到它的工作,使我的包装类可以用一个初始化列表初始化,因为这样:

  enum_addressable_array&LT;焦炭,3,E&GT; EA = {'一','B','C'};


解决方案

这是的std ::阵列&LT;&GT; 没有构造函数接受一个的std :: initializer_list&LT;&GT; (初始化列表构造器),有什么可能意味着通过一个的std :: initializer_list&LT没有特别的语言支持;&GT; 一类的构造函数,这样可以正常工作。这样失败。

有关它的工作,你的派生类需要捕捉所有元素,然后转发,构造模板:

 模板&LT; typename的... E&GT;
enum_addressable_array(E&安培;&安培; ... E):base_t {{性病::向前&LT; E&GT;(五)...}} {}

请注意,您需要 {{...}} 在这种情况下,因为梅开二度省音(像你的情况省略括号)不会在那个地方工作。它只能在窗体的声明 T T = {...} 。因为一个的std ::阵列&LT;&GT; 由一个结构嵌入原始阵列,这将需要两个层次括号中。不幸的是,我相信,确切的团粒结构的std ::阵列&LT;&GT; 是不确定的,所以你需要希望,它适用于大多数实现

Possible Duplicate:
How do I initialize a member array with an initializer_list?

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

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

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'};

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'};

解决方案

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)...}} {}

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 ::数组对象与初始化列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆