【问题标题】:What's wrong with std::unique_copy (or my use of it)?std::unique_copy (或我对它的使用)有什么问题?
【发布时间】:2016-10-22 03:11:28
【问题描述】:

我大概有以下代码应该将唯一的段索引收集到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 并错误地使用了它?

【问题讨论】:

  • s/uniques.begin()/back_inserter(uniques)/
  • reserve != resize。所以你的unique_copy 是错误的,或者你应该使用back_inserter
  • @Arunmu 你是在暗示向量的random_access_iterator 不是output_iterator
  • @Arunmu 我明白你在说什么,但情况并非如此。它们只是这里的模板名称,用于尝试执行一个概念。根据标准,没有标签或硬性要求。只要容器有空间,任何迭代器都可以工作。如果它没有空间,那么你需要像 back_inserter 这样的东西来为你创建它。

标签: c++ stl std standard-library c++-standard-library


【解决方案1】:

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

正如 cmets 中已经指出的那样,无论如何都有一种巧妙的方法来使用 unique_copy。您将其更改为使用 back_inserter 作为目标范围。

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

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

【讨论】:

    猜你喜欢
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    相关资源
    最近更新 更多