Search code examples
c++queuec++98

How to efficiently transfer the contents of an std::queue to another in C++98?


In C++11 or higher, one can efficiently transfer all the contents of one std:queue instance to another std::queue instance through std::move(). The system I am working with, however, is only C++98. How can I do the same operation (efficiently) in C++98?


Solution

  • For C++98 you'd need to reach into the the protected c member, and swap those containers. Swapping is meant to be fast and exception safe (and indeed is for standard containers), and is the idiom one would use prior to the addition of std::move.

    You can do that with derivation, and pointers to members.

    template<typename E, class C>
    void swapQueues(std::queue<E, C>& lhs, std::queue<E, C>& rhs) {
        struct peek : std::queue<E, C> {
            using std::queue<E, C>::c; // Grant access
        };
        C std::queue<E, C>::* ptr = &peek::c;
        (lhs.*ptr).swap(rhs.*ptr);
    }
    

    We derive peek from the queue type so as to obtain a class type that can access the c member. We then immediately expose that member in peek.

    Following that, we fetch a pointer to the member through the public peek::c. Pointer-to-member conversion is implicit here, allowing us to initialize a pointer-to-member of std::queue.

    And finally, it's a simple matter of applying the pointer-to-member to get a reference to each queue's underlying container, and swapping them.

    Here it is live