标签: stddeque

为什么std :: deque不允许指定存储桶大小?

std::deque将元素存储在固定大小的“存储桶”(数组)中。不同的编译器使用不同的存储桶大小:

  • MSVC:16个字节或元素大小(如果更大)
  • GCC:512字节或元素大小(如果更大)
  • 铛: element_size < 256 ? 4096 : element_size * 16

对于MSVC(尤其是MSVC)和GCC,如果双端队列元素的大小大于硬编码的大小,std::dequestd::list在大多数情况下会导致性能下降。

我认为Clang的效果更好,无论双端队列元素的大小如何,存储桶至少应包含16个元素。尽管在某些情况下,对于小元素,最小的bucket大小4096字节可能不是最佳的。

为什么没有std::deque用于存储桶大小的附加模板参数,其默认值是供应商认为合理的值?这不会破坏向后兼容性,但可以优化性能。

c++ stddeque

18
推荐指数
1
解决办法
300
查看次数

为什么std :: queue使用std :: dequeue作为底层默认容器?

正如cplusplus.com上所读,std::queue实现如下:

队列实现为容器适配器,它是使用特定容器类的封装对象作为其底层容器的类,提供一组特定的成员函数来访问其元素.元素被推入特定容器的"后面"并从其"前面"弹出.

底层容器可以是标准容器类模板之一或其他一些专门设计的容器类.该底层容器应至少支持以下操作:

......

标准容器类dequelist满足这些要求.默认情况下,如果没有为特定队列类实例化指定容器类,则使用标准容器双端队列.

我很困惑为什么deque(类固醇上的双端队列)在这里被用作默认值,而不是list(这是一个双向链表).

在我看来,这std::deque是非常矫枉过正:它是一个双端队列,但也有恒定时间元素访问和许多其他功能; 基本上是一个功能齐全的std :: vector bar'元素在内存中连续存储'保证.

正常情况下std::queue只有极少数可能的操作,在我看来,双向链表应该更有效率,因为需要在内部发生的管道要少得多.


为什么然后std::queue使用std::deque默认值而不是std::list

c++ queue stl c++11 stddeque

8
推荐指数
2
解决办法
1830
查看次数

在 C++11 中将 std::vector 移动到 std::deque

如果我有std::deque并且std::vector想要将它们组合到std::deque,我可以通过以下方式进行:

typedef int T; // type int will serve just for illustration
std::deque< T > deq(100); // just some random size here
std::vector< T > vec(50);
// ... doing some filling ...
// now moving vector to the end of queue:
deq.insert( 
    deq.end(), 
    std::make_move_iterator( vec.begin() ),
    std::make_move_iterator( vec.end() )
);
std::cout << deq.size() << std::endl;
Run Code Online (Sandbox Code Playgroud)

我们知道向量的大小,但我们不能在最后std::deque使用之前保留内存std::deque.insert(...)。那么这是将所有元素移动std::vector到末尾的最快方法std::deque吗?还是我错过了什么?

谢谢你。

c++ stdvector c++-standard-library c++11 stddeque

7
推荐指数
1
解决办法
3892
查看次数

从std :: deque线程对emplace_back()和operator []()的并发调用是否安全?

来自emplace_back()以下文档的摘录:

  • 迭代器有效性

与此容器相关的所有迭代器都是无效的,但指针和引用仍然有效,指的是它们在调用之前引用的相同元素.

  • 数据竞赛

容器已修改.

调用不访问任何包含的元素:同时访问或修改它们是安全的(尽管请参见上面的迭代器有效性).

以及以下文档的摘录operator[]():

  • 数据竞赛

访问容器(const和非const版本都不会修改容器).

可能会访问或修改元素n.同时访问或修改其他元素是安全的.

因此,鉴于deque的某个实例至少有一个元素,通过访问它operator[]()并同时调用emplace_back()容器确实是线程安全的?

我倾向于说它是,但不能决定"访问" emplace_back()的文档是否包括使用operator[]()如下:

int access( std::deque< int > & q )
{
    return q[ 0 ];
}

void emplace( std::deque< int > & q , int i )
{
    q.emplace_back( i );
}
Run Code Online (Sandbox Code Playgroud)

其中两个函数同时调用,或者"访问"仅适用于已经采用某些引用或指针的元素:

std::deque< int > q { 1 };

auto * ptr = & q[ 0 ]

std::thread t1 ( [ …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-safety stddeque

5
推荐指数
1
解决办法
1276
查看次数

使用类的const成员使用std :: deque :: erase编译错误

我在这里得到一个编译错误,我不知道代码有什么问题.我正在使用g ++ 4.9.2.

#include<iostream>
#include<deque>

using std::string;
using std::deque;

class Dummy {
public:
    virtual ~Dummy(){};
    Dummy():ID_("00") {};
private:

    const string ID_;
};

int main(){
    {
    deque <Dummy> waiter;
    waiter.push_back(Dummy());
    waiter.erase( waiter.begin() );
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我知道删除const会删除编译错误,但我不知道为什么.无论如何,我需要这个const.

c++ stddeque

2
推荐指数
1
解决办法
241
查看次数

为什么这个 C++ 双端队列代码在我解调时“效率较低”?

这是我在 HackerRank 上研究这个问题的解决方案时遇到的一个问题。它基本上归结为以下内容:给定一个数组 A 和一个整数 K,问题要求您找到大小为 K 的 A 的每个连续子数组的最大值。还有一些额外的东西(对于每个测试用例,这个问题都会发生 T次,并且必须从输入中读取才能获得 A),但这就是它的要点。

该站点会检查您的答案是否足够有效,即使您的代码最终产生了正确的输出,也可能会因超时而导致提交失败。现在,当您第一次进入代码区域时,有一些预定义的代码供您使用:

#include <iostream>
#include <deque> 
using namespace std;

void printKMax(int arr[], int n, int k){
    //Write your code here.
}

int main(){

    int t;
    cin >> t;
    while(t>0) {
        int n,k;
        cin >> n >> k;
        int i;
        int arr[n];
        for(i=0;i<n;i++)
            cin >> arr[i];
        printKMax(arr, n, k);
        t--;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,该站点已经为您的利益处理输入,并为您指明模块化方法。你所要做的就是解决连续子数组问题;我使用以下函数完成了它,该函数通过了所有测试用例:

void printKMax(int arr[], int n, int k){
    // Queue will store …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm performance deque stddeque

2
推荐指数
1
解决办法
211
查看次数

为什么要使用std :: stack或std :: queue?

我为什么要使用a std::stack或a std::queue而不是a std::vector或a std::deque

由于容器适配器只是标准容器周围的包装器,为什么要使用它们呢?

c++ stack containers stdvector stddeque

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

STL容器选择和删除随机项目?

我正在实现的算法具有以下结构:

while C is not empty
  select a random entry e from C
  if some condition on e
    append some new entries to C (I don't care where)
  else
    remove e from C
Run Code Online (Sandbox Code Playgroud)

重要的是循环 e 的每次迭代都是随机选择的(具有统一的概率)。

理想情况下selectappendremove步骤都是 O(1)。

如果正确地明白,使用std::listappendremove步骤将是O(1),但随机选择将是O(N)(例如,使用std::advance如在此解决方案)。

And std::deque and std::vector seem to have complementary O(1) and O(n) operations.

I'm guessing that std::set will introduce some O(log n) complexity.

Is there any …

c++ stl stdlist stdvector stddeque

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

是否可以在 C++ 中添加到空双端队列的迭代器中?

以下是导致问题的原因的示例:

#include <deque>

int main() {
    std::deque<int> has_data = {1, 2, 3};
    std::deque<int>::iterator iter1 = has_data.begin() + 5; // This works fine
    
    std::deque<int> had_data = {4, 5, 6};
    had_data.clear();
    std::deque<int>::iterator iter2 = had_data.begin() + 5; // This also works fine
    
    std::deque<int> is_empty;
    std::deque<int>::iterator iter3 = is_empty.begin() + 5; // This causes a segfault
}
Run Code Online (Sandbox Code Playgroud)

如果双端队列之前从未包含任何元素,则添加到空双端队列的迭代器似乎只是一个问题。

我很好奇这是否是 STL 中的错误,或者我是否只是以导致未定义行为的方式使用它。我只在使用 Xcode(GUI 和命令行)编译时遇到这个问题。我也在 Linux 上使用 GCC 6.2.0 版尝试过它,但那里似乎不存在问题。

c++ iterator stl stddeque c++17

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