3

I have this interesting situation.

I have a bunch of structs that hold a string.

struct foo
{
    string mStringName;
}
vector<foo> mFoos;

I also have a queue of string references

queue<string&> mStringQueue;

And finally, I have a function that accepts a const string&

void Bar(const string&);

Heres the situation.

//...in some loop
currentFoo = mFoos[index];

// Queue up the string name.
mStringQueue.push(currentFoo.mStringName);


//...Later on, go through our queue and pass each one to the function.

for (int queueIndex = 0; queueIndex < mStringQueue.size(); queueIndex++)
{
    Bar(mStringQueue.front());
    mStringQueue.pop();
}

This gives me the following compile error:

error C2664: 'std::queue<_Ty>::push' : cannot convert parameter 1 from 'String' to 'String &(&)'

I'm definitley having trouble wrapping my mind around string references and whatnot, so any help would be greatly appreciated

MintyAnt
  • 2,978
  • 7
  • 25
  • 37

2 Answers2

8

Reference types do not meet the requirements of types that can be used in standard containers. In particular they are not copyable. Note that while the referenced object can be copyable or not, the reference itself is never copyable.

The alternative is to store pointers, which are copyable.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • I was trying to use references because the data is not dynamic. How would I go about using a queue? myQueue.push(new STRING(foo->mStringName)); or myQueue.push(&foo->mStringName)); – MintyAnt May 04 '12 at 20:28
  • Since you already have them stored, you can go for the second option so as not to duplicate the data. That also frees you from the burden of manually `delete`ing the strings later. –  May 05 '12 at 06:13
3

Standard containers require "T is copyable (strictly speaking, CopyConstructible)" or "T is movable (strictly speaking, MoveConstructible)". If you need reference element, you can use std::queue< std::reference_wrapper< T > >.

#include <cassert>
#include <queue>
#include <functional> // std::reference_wrapper, std::ref

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;

    std::queue<std::reference_wrapper<int>> que;

    que.push(std::ref(a));
    que.push(std::ref(b));
    que.push(std::ref(c));

    while (!que.empty()) {
        que.front() += 1;
        que.pop();
    }

    assert(a == 2);
    assert(b == 3);
    assert(c == 4);
}
Akira Takahashi
  • 2,912
  • 22
  • 107