Search code examples
c++boostconstructorlock-free

How to pass capacity size to lock-free spsc_queue via constructor


I'm wrapping boost::lockfree::spsc_queue<T> queue into a RingBuffer class, and want to be able to use this RingBuffer in my project. But I am having difficulty passing capacity size to queue via class constructor.

RingBuffer.hh

template<class T>
class RingBuffer {
private:
    int capacity;
    boost::lockfree::spsc_queue<T> queue;

public:
    explicit RingBuffer(int size)
    {
        if(size < 2){
            capacity = 2;
        } else {
            capacity = size;
        }
        queue(capacity); // Error here. Not working in this way
    }

    ~RingBuffer()
    = default;

    int Insert(); // queue.push()
    int Extract(); // queue.pop()
}

In main.cpp

int main(int argc, char *argv[]) {

    auto ringBuffer = new RingBuffer<int>(3); // capacity size: 3 

    // ...
    // other things done
    // ...

    delete ringBuffer;
    return 0;
}

I expect this would work for me, but I get error: error: type 'boost::lockfree::spsc_queue<int>' does not provide a call operator. @ queue(capacity) inside the constructor of RingBuffer.

So, how can I achieve this?


Solution

  • spsc_queue doesn't have operator()(int) in its interface. Now your compiler complains to queue(capacity); - this calls opearator()(int) on queue instance.

    I assume your intention is to call ctor of spsc_queue with capacity as argument.

    So add helper method to calculate this capacity and pass it to queue constructor on initialization list:

    template<class T>
    class RingBuffer {
    private:
        int capacity;
        boost::lockfree::spsc_queue<T> queue;
    
    public:
    
        int getCapacity(int size) {
            if(size < 2){
                capacity = 2;
            } else {
                capacity = size;
            }
            return capacity;
        }
    
        explicit RingBuffer(int size)
          : queue( getCapacity(size) )  // call ctor on initialization list
        {
    
        }
    
        ~RingBuffer()
        = default;
    
        int Insert(); // queue.push()
        int Extract(); // queue.pop()
    };
    

    Demo