Why std::queue requires the element to be copyable?

Viewed 88

In the code below std::deque compiles, but std::queue does not:

class A
{
public:

    explicit A(int a) : m_a(a)
    {
        ++count;
    }

    ~A()
    {
        --count;
    }

    A(A const &) = delete;

    A(A && other) : A(other.m_a)
    {
        other.m_moved = true;
    }

    A & operator = (const A &) = delete;

    A & operator = (A && other)
    {
        m_a = other.m_a;
        other.m_moved = true;

        return *this;
    }

    bool operator == (const A & other) const
    {
        return m_a == other.m_a;
    }

    bool operator != (const A & other) const
    {
        return !operator==(other);
    }

    bool operator < (const A & other) const
    {
        return m_a < other.m_a;
    }

    static int count;

private:


    bool m_moved = false;
    int m_a;
};

int A::count = 0;

int main()
{
    std::deque<A> d;
    std::queue q(d);

    q.push(A(1));

    return 0;
}

but if I make class A copyable by changing A(A const &) = delete; with A(A const &) = default; it starts to compile.

What is the logic behind this? As far as I can see, std::deque is an adapter that does not add some extra functionality.

1 Answers

Elements are copied when you construct queue from deque, but you've deleted copy constructor for deque's value type (A). So you need to move d when constructing queue.

...

int main()
{
    std::deque<A> d;
    std::queue q(std::move(d));  // added std::move

    q.push(A(1));

    return 0;
}
Related