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。
我大致有以下代码应该将唯一的段索引收集到 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。