标签: iterator

spled()on std :: list和iterator invalidation

3参数形式list::splice()将单个元素从一个列表移动到另一个列表. SGI的文档明确声明所有迭代器,包括指向要移动的元素的迭代器仍然有效. Roguewave的文档没有说明splice()方法的迭代器失效属性,而C++标准明确声明它使所有迭代器和对被拼接元素的引用无效.

splicing()在实践中按照SGI的定义工作,但是我在微软的STL实现的调试/安全SCL版本中得到断言失败(解除引用无效迭代器)(严格遵循标准的字母).

现在,我正在使用list完全是因为我想在列表之间移动一个元素,同时保留指向它的迭代器的有效性.该标准对最初的SGI规范进行了极为无益的改变.

我该如何解决这个问题?或者我应该是务实,在沙把头(因为拼接并没有在实践中迭代器失效-甚至在MS的执行,一旦调试迭代器关闭).

c++ containers iterator list

11
推荐指数
1
解决办法
3401
查看次数

guava-libraries:Iterators.cycle()线程安全吗?

假设我有以下课程:

public class Foo {  

    private List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
    private Iterator<Integer> iterator = Iterators.cycle(list);  

    public void bar(){  
        Integer value = iterator.next();  
        doSomethingWithAnInteger(value);
    }  
}  
Run Code Online (Sandbox Code Playgroud)

如果一个Foo实例被两个线程同时访问,我需要每个线程从中获取不同的值iterator.next().该bar()方法是否必须同步?或者iterator.next()保证是线程安全的?

在这个例子中,我使用ArrayList作为底层的Iterable.循环迭代器的线程安全性是否依赖于特定的可迭代实现?

谢谢.

java iterator thread-safety guava

11
推荐指数
2
解决办法
4204
查看次数

Scala迭代器与地图和为

鉴于:

val list = List("one","two","three")     
val it = list.toIterator
Run Code Online (Sandbox Code Playgroud)

我可以跑:

list map ("_" +) -> List(_one, _two, _three)
for (i <- list) yield("_" + i) -> List(_one, _two, _three)
Run Code Online (Sandbox Code Playgroud)

如果我在迭代器上运行相同的操作,我得到:

it map ("_" + ) -> Iterator[java.lang.String] = empty iterator
for (i <- it) yield("_" + i) -> Iterator[java.lang.String] = empty iterator
Run Code Online (Sandbox Code Playgroud)

在我运行map/for之后,我不应该再找回另一个(非空的)Iterator [String]吗?

iterator for-loop scala map scala-collections

11
推荐指数
1
解决办法
1万
查看次数

std :: list <> :: splice使迭代器无效.什么道理呢?

我想知道使std::list<>::splice引用新子容器中的子序列的迭代器无效的原因是什么.这看起来有点不合逻辑,特别是在标准std::container::swap规格方面.根据语言标准std::container::swap 不会使任何迭代器无效.这是一个非常合理的实用规范.但是,我会说这std::list<>::splice也会从保留迭代器的行为中获益匪浅.

我理解可能存在基于迭代器可达性等概念的纯粹学术考虑.但同时splice也是一种std::list特定的操作,这意味着为它提供定制的规范可能不会对其造成严重的概念损害.一般的STL设计.

那是什么?它会使一些std::list我认识不到的实际实施变得非法或过于复杂吗?

c++ iterator stl invalidation

11
推荐指数
1
解决办法
805
查看次数

使用copy和back_inserter将向量附加到自身时出现错误的结果

这个问题的启发,询问如何将一个向量附加到自身,我的第一个想法是以下(是的,我意识到insert现在是一个更好的选择):

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main() {
    std::vector<int> vec {1, 2, 3};
    std::copy (std::begin (vec), std::end (vec), std::back_inserter (vec));

    for (const auto &v : vec)
        std::cout << v << ' ';
}
Run Code Online (Sandbox Code Playgroud)

但是,这打印:

1 2 3 1 * 3
Run Code Online (Sandbox Code Playgroud)

每次运行程序时*都是不同的数字.只有2被替换的事实是特殊的,如果真的有解释,我会有兴趣听到它.继续,如果我附加到不同的向量(原始副本),它会正确输出.如果我在前一行之前添加以下行,它也会正确输出copy:

vec.reserve (2 * vec.size());
Run Code Online (Sandbox Code Playgroud)

std::back_inserter尽管事先没有预留内存,但我认为这是一种将元素添加到容器末端的安全方法.如果我的理解是正确的,复制线有什么问题?

我假设它与编译器无关,但我使用的是GCC 4.7.1.

c++ iterator stl undefined-behavior stl-algorithm

11
推荐指数
1
解决办法
1347
查看次数

std :: iterator,指针和VC++警告C4996

int *arr = (int*) malloc(100*sizeof(int));
int *arr_copy = (int*) malloc(100*sizeof(int));
srand(123456789L);
for( int i = 0; i < 100; i++) {
    arr[i] = rand();
    arr_copy[i] = arr[i];
}

// ------ do stuff with arr ------

// reset arr...
std::copy(arr_copy, arr_copy+100,  arr);
Run Code Online (Sandbox Code Playgroud)

在编译时,我得到以下警告std::copy():

c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2227):
warning C4996: 'std::_Copy_impl': Function call with parameters that may be
unsafe - this call relies on the caller to check that the passed values are 
correct. To disable this warning, …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm iterator stl

11
推荐指数
3
解决办法
1万
查看次数

如何定义is_iterator类型特征?

  • 我正在尝试编写一个is_iterator<T>类型特征.凡当T是一个迭代器类型is_iterator<T>::value == true,否则是is_iterator<T>::value == false.

  • 到目前为止我尝试了什么:


template <class, class Enable = void> 
struct is_iterator : std::false_type {};

template <typename T> 
struct is_iterator<T, typename std::enable_if<std::is_pointer<typename
     std::iterator_traits<T>::pointer>::value>::type> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)

LIVE DEMO


问:是否有更合适的方式来定义is_iterator类型特征而不是上面显示的类型特征?

c++ iterator type-traits c++11 c++14

11
推荐指数
2
解决办法
1982
查看次数

为什么迭代器在Python文档中被认为是函数式的?

我试图理解迭代器.我注意到Python文档认为迭代器是一个功能样式的构造.我真的不明白.

迭代器里面有一个状态是不是真的.所以当你调用时it.__next__(),你会改变迭代器的状态.据我所知,对象的变异状态不被认为是功能性的,因为函数式编程强调对象/闭包的不变性和组合能力.

实际上,问题出现了,因为我想编写一个Scheme过程/函数,它接受令牌并返回一个迭代器.

(define tokens->iterator
  (lambda ls
    (lambda ()
      (if (null? ls)
          '*eoi*
          (let ((tok (car ls)))
            (set! ls (cdr ls))
            tok)))))
Run Code Online (Sandbox Code Playgroud)

请注意我必须使用set!变异ls,这就是我提出这个问题的方法.

要使用它,

(define it (tokens->iterator 1 '+ 2))
Run Code Online (Sandbox Code Playgroud)

要测试它,

scheme@(guile-user)> (it)
$2 = 1
scheme@(guile-user)> (it)
$3 = +
scheme@(guile-user)> (it)
$4 = 2
scheme@(guile-user)> (it)
$5 = *eoi*
scheme@(guile-user)> (it)
$6 = *eoi*
Run Code Online (Sandbox Code Playgroud)

只是为了好玩,我还将其翻译成Python:

def tokens_to_iterator(*tup):
    ls = list(tup)
    def iterator():
        if not ls:
            return "*eoi*"
        else:
            tok = …
Run Code Online (Sandbox Code Playgroud)

python scheme iterator

11
推荐指数
2
解决办法
462
查看次数

为什么标准容器迭代器不会重载` - >*`?

->*如果重载->,显然不能自动工作,并且必须手动重载.

为什么标准容器迭代器不超载->*除了->,迫使使用(*iter).*mem_ptr代替iter->*mem_ptr

#include <iostream>
#include <vector>

struct S
{
    int x;
};

int main()
{
    std::vector<S> vec = {{42}};
    auto mem_ptr = &S::x;

    std::cout << (*vec.begin()).*mem_ptr << '\n'; // This line compiles.

    std::cout << vec.begin()->*mem_ptr << '\n'; // This line doesn't compile.
}
Run Code Online (Sandbox Code Playgroud)

c++ iterator operator-overloading language-lawyer

11
推荐指数
1
解决办法
169
查看次数

为什么范围的算法与std的迭代器不兼容?

#include <vector>
#include <iostream>
#include <range/v3/all.hpp>

int main()
{
    auto coll = std::vector{ 1, 2, 3 };

    ranges::copy(
        coll,
        ranges::ostream_iterator<int>{  std::cout, ", " }
    ); // ok

    ranges::copy(
        coll, 
        std::ostream_iterator<int>{ std::cout, ", " }
    ); // error 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.

如果是这样,为什么范围的算法不与std的迭代器兼容?

c++ iterator c++-concepts range-v3 c++20

11
推荐指数
1
解决办法
528
查看次数