提取 std::initializer_list<T> C++的一部分

Extracting a part of an std::initializer_list<T> C++

本文关键字:gt C++ 一部分 std list 提取 lt initializer      更新时间:2023-10-16

i具有一种方法bar(...),该方法 std::initializer_list<T>参数。该方法调用另一种方法foo(...),该方法还采用了类型std::initializer_list<T>的参数。foo应与bar相同的参数调用,但没有initializer_list的第一个元素。

bar(std::initializer_list<int> l)
{
     ...
     auto l = t.begin();
     ++l;
     foo(new std::initializer_list<int>(l, t.end()));
}

我尝试了上面的代码,但是我只是意识到std::initializer_list<T>在开头和initializer_list<T>的结尾都无法从迭代器中构造,并给出了预期的结果。它以整数来解析迭代器。

auto t = new std::initializer_list<int>{1, 2, 3, 4, 5};
auto l = t.begin();
++l;
auto k = new std::initializer_list<int>(l, t.end());

这使我的问题变得更加困难。

另一个想法是将std::initializer_list转换为数组,然后将数组回到std::initializer_list,但更短。对我来说这似乎很愚蠢。而且我不确定如何在运行时制作std::initializer_list,即使在该数组的帮助下。

初始化器列表是一个简单的值包装器,用列表语法, { 1, 2, 3 }声明。它的通常目的是传递给某些函数,该功能将以更智能的方式从初始化列表中处理对象。

初始化列表没有接受迭代器的修改器方法或构造函数。

阵列的想法更加足够。示例:

void bar( std::vector<int> _a)
{
    for( int x : _a )
        std::cout << x << ' ';
}
void foo( std::initializer_list<int> _a)
{
    bar( {_a.begin() + 1, _a.end()} );
}
int main()
{
    foo( {1, 2, 3} );
    return 0;
}

来自 std::initializer_list

初始化列表可以作为一对指针或指针和长度实现。复制std :: initializer_list不会复制基础对象。

std::initializer_list没有复制构造函数,而只有一个默认的构造函数,该构造器可用于构造空列表。它们被用作指定只读列表的一种方式。

在您的函数示例中bar

void bar(std::initializer_list<int> l)
{
     // [...]
     auto it = t.begin();
     ++it;
     foo(/*foo arguments (see below)*/);
}

初始化器列表的范围l超出了foo的执行。因此,在这种情况下,用一对迭代器实现foo是完全有效的:

void foo( InputIt first, InputIt last )
{
    std::for_each( first, last, []( int x ) {
      std::cout << x << ' ';
    });
}

这样的优点是bar可以与任何类型的容器一起使用。在大多数情况下,您只需要知道如何迭代它,而不是如何真正存储元素。从现在开始,它可以与迭代器一起使用,您可以使foo完全通用:

template < typename Container >
void bar( Container c ) {
    auto first = std::next(std::begin(c));
    foo( first, std::end(c) );
}

已知大小时,即使使用C风格数组也可以使用:

int a[5] = {1,2,3,4,5};
bar(a);