Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

When resizing a std::vector of std::queue. Compile error; static assertion failed: result type must be constructible from value type of input range

I got the following class:

class  Buf  {
    const uint8_t *data;
    size_t size;
public:
    Buf() : data(nullptr), size(0) {};
    Buf(const uint8_t *data_, size_t size_) : data(data_), size(size_) { };
    Buf(Buf&& other) noexcept
        : data{std::exchange(other.data, nullptr)}, size{other.size} {};

    Buf& operator=(Buf&& other) noexcept {
        data = std::exchange(other.data, nullptr);
        size = other.size;
        return *this;
    }
    Buf(const Buf& other) = delete;
    Buf& operator=(Buf other) = delete;


    ~Buf()
    {
        free((void *)data);
    }
};

I use this class inside a queue

int main()
{
    std::vector<std::queue<Buf>> data;
    data.resize(10); // compile error
    return 0;
}

I get a long compile error boiling down to:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

error: static assertion failed: result type must be constructible from
value type of input range

If I in turn use a std::deque instead it seems to compile.

So why does not work with std::queue and how could it be fixed. And why does it seem to work with std::deque

The code: https://godbolt.org/z/Ev86YG1nG

>Solution :

std::queue is a container adapter; that is, it forwards all of its actual operations to an internal container of a type specified by a template argument. By defualt, this container is std::deque.

However, std::deque<T> is not noexcept moveable. Therefore, when vector<T> attempts to resize itself, it cannot use the move operation; it must copy it. And since Buf is not copyable, neither is std::deque<Buf>. So vector tries to copy a non-copyable type; hence the compile error.

There’s not really a good solution to this. vector is not a good type for a queue, since insertion/removal at the front is slow. And deque is not noexcept moveable, nor is list. Maybe if the queues are small, using std::queue<Buf, std::vector<Buf> might work out performance-wise.

Using std::deque for the outer container works because many of its operations do not require the type to be moveable or copyable. Insertion/removal from the head/tail don’t provoke copying.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading