Matoe
Matoe

Reputation: 2758

How to initialize a reference to an empty STL container in a constructor?

The question pretty much says it all. I need to initialize a reference to an empty STL container (more precisely, std::set).

Attempting to:

typedef std::set<bozo *> bozo_set;
class BozoClass { public: BozoClass(): bozosetref(bozo_set()) {} }

will obtain compiler errors similar to:

bozo.cc:104: error: invalid initialization of non-const reference of type ‘bozo_set&’ from a temporary of type ‘bozo_set’

(Just a side note: this is not asking whether I should or not use typedef for this or not. I take comments about it, but this isn't really the actual question.)

EDIT: Since there've been a lot of comments about this, the point of having a reference to this is to allow outer classes to change bozo elements of this set, instead of having a ton of unneeded methods in BozoClass to manage the set.

Upvotes: 1

Views: 851

Answers (3)

John Dibling
John Dibling

Reputation: 101446

The problem you're having is actually well-described by the compiler error:

invalid initialization of non-const reference of type ‘bozo_set&’ from a temporary of type ‘bozo_set’

The compiler is telling you that you are trying to take the reference of a temporary. You can't* do this because the thing you are taking a reference to is temporary. In other words, it will cease to exist immediately. The temporary being referred to is the bozo_set you are constructing here:

bozosetref(bozo_set())
           ^^^^^^^^^^

As soon at the expression bozosetref(bozo_set()) has finished executing, the set instantiated in bozo_set() will be destroyed.

Presumably, bozosetref is a member variable of type set<bozo*>&.

It seems to me like BozoClass is intended to own the set that you are trying to take a reference to. That is fine, but the way you normally do that is by not taking a reference to the set, but by simply instantiating one directly:

class BozoClass 
{ 
public: 
  BozoClass() {}
private:
  set<bozo*> mBozos;
};

Now, mBozos is not a reference to the set, but the set itself.

You can then provide a reference to it to clients of BozoClass through an accessor:

class BozoClass
{
public:
  // ...
  set<bozo*>& GetBozos() { return mBozos; }
};

Clients can in turn use & modify the set directly through this accessor:

int main()
{
  BozoClass bc;
  bc.GetBozos().insert (new bozo); // or something
}

  • Actually, you can but shouldn't do this. Since the set itself hasn't been assigned to a variable, there is nothing "holding" on to it. The reference you took to it becomes invalid.

Upvotes: 1

user405725
user405725

Reputation:

#include <set>

struct Class {
    Class() : set(), setref(set) {}

    std::set<void *> set;
    std::set<void *> &setref;
};

Upvotes: 1

alexrider
alexrider

Reputation: 4463

You cannot pass references to non const objects.
In your case if such thing would be allowed you would get reference to the already deleted temporarily instance of bozo_set in your class, but not a reference to an empty set.

Upvotes: 0

Related Questions