是否可以使用 begin() 和 end() 创建 std::array?

Posted

技术标签:

【中文标题】是否可以使用 begin() 和 end() 创建 std::array?【英文标题】:Is it possible to create std::array using begin() and end()? 【发布时间】:2016-12-06 17:05:07 【问题描述】:
std::array<int, 4> myarray = 1, 2, 3, 4;
std::array<int, 4> myarray2(std::begin(myarray),std::end(myarray)); //It throws error

如果我可以创建myarray2 的唯一方法是将两个std::array&lt;int, 4&gt;::iterator 传递给构造函数,我是否可以使用std::array 来实现它,还是必须使用vector

【问题讨论】:

查看一些基本参考资料会发现构造函数是隐式声明的,并且必须遵循聚合初始化的规则。由于这不包括迭代器,所以答案是否定的。请记住,std::array 代表一个固定/静态数组,就像传统的 C 样式数组一样。 您打算使用 C++17 吗? en.cppreference.com/w/cpp/container/array/begin 既然你知道数组的大小,你可以计算*std::begin(myarray)*std::next(std::begin(myarray))等,并使用通常的聚合语法std::array&lt;int, 4&gt; myarray2a,b,c,d;构建myarray2。 【参考方案1】:
template<class T, std::size_t N, class It>
std::array<T,N> array_from_iterator(It it)
  return indexer<N>()(
    [it](auto...Is)->std::array<T,N>
    
      return  (*(it+Is))... ;
    
  );

indexer 在哪里:

template<class=void,std::size_t...Is>
auto indexer(std::index_sequence<Is...>)
  return [](auto&&f)->decltype(auto)
    return decltype(f)(f)( std::integral_constant<std::size_t,Is>... );
  ;

template<std::size_t N>
auto indexer()
  return indexer(std::make_index_sequence<N>);

为我们做了哪些参数包扩展。没有边界检查。未编译,可能有 tpyos。

C++14,我不保证 MSVC 可以正常工作。

std::array<int, 4> myarray2 = array_from_iterator<int,4>(std::begin(myarray));

可以修改为与我怀疑的非随机访问迭代器一起使用。

【讨论】:

【参考方案2】:

您可以定义您的 custom_array,它继承自标准 std::array。

 template<typename _T, size_t _size>
    class custom_array : public std::array<_T, _size> 
    public:
        custom_array(std::array<_T, _size> arr, 
                     size_t start, 
                     size_t end) 

            size_t itr = 0;

            while (itr < this->size() &&
                   start < arr.size() && 
                   start <= end) 
                this->_Elems[itr++] = arr[start++];
            
        

        custom_array(std::array<_T, _size>::iterator start,
                     std::array<_T, _size>::iterator end) 
            size_t itr = 0;
            while (itr < this->size()) 
                this->_Elems[itr++] = *start;
                start++;
                if (start == end)  break; 
            
        
    ;

然后你可以随意声明你的custom_array,例如:

std::array<int, 4> arr =  1, 2, 3, 4 ;
custom_array<int, 4> arr_1(a, 0, 4);
custom_array<int, 4> arr_2(a.begin(), a.end());

【讨论】:

这样做(继承)的明显缺点是您失去了std::array 的聚合状态,这是它的主要优点之一。 Aggregates cannot have base classes. 你能举个具体的例子吗? 我不明白你的意思。聚合的具体例子? std::array 是一个聚合类型。当您继承它时,您将失去该状态;您的派生类custom_array 不是 聚合。有关什么是聚合以及它们的特殊之处的更多信息,请参阅here。

以上是关于是否可以使用 begin() 和 end() 创建 std::array?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确总结datetime(end_date和begin date之间的区别) - mysql

正则表达式 - 匹配 BEGIN 和 END 之间的所有内容

SQL中begin end 啥意思?怎么用着条语句?

为 C++ 选择 begin() 和 end()

BEGIN 和 END 中的 Oracle 公用表表达式 (WITH)

使用 while-begin-end 循环时 SQL native 和 JDBC 的区别