std::unique_copy(或我对它的使用)有什么问题?

What's wrong with std::unique_copy (or my use of it)?

我大致有以下代码应该将唯一的段索引收集到 uniques:

    vector< int > segments;
    // segments vector is filled in here
    // ...
    sort( segments.begin(), segments.end() );
    vector< int > uniques;
    uniques.reserve( segments.size() );
#ifdef USE_STD_UNIQUE_COPY
    unique_copy( segments.begin(), segments.end(), uniques.begin() );
#else
    if( segments.size() > 0 )
        uniques.push_back( segments[ 0 ] );
    for( size_t i = 1; i < segments.size(); ++i)
    {
        if( segments[ i ] != uniques.back() )
            uniques.push_back( segments[ i ] );
    }
#endif

当定义 USE_STD_UNIQUE_COPY 时,代码失败;当它未定义时,它会按预期工作。整个作品在多个线程上运行,我还没有调试 std::unique_copy 输出究竟有何不同。无论如何,根据 cppreference std::unique_copy (1) 应该完全按照代码的 #else 部分执行。

于是问题来了:这张图有什么问题吗? std::unique_copy 是否有限制,也许不是线程安全的?或者我可能误读了 cppreference 并错误地使用了它?

问题是您正在尝试复制到无效的目标范围。本质上,您对 reserve 的调用分配了向量需要的 space ,但实际上并没有改变它的大小。所以你不能直接复制到它的元素。您的替代代码有效,因为对 push_back 的调用将向量大小扩展 1 并附加到末尾。

正如评论中已经指出的那样,有一个巧妙的方法可以使用 unique_copy。您将其更改为使用 back_inserter 作为目标范围。

unique_copy(segments.begin(), segments.end(), back_inserter(uniques)); 

back_inserter 创建一个 back_insert_iterator,当复制到该容器时,会在容器上调用 push_back。