Вопрос в значительной степени говорит обо всем этом. Мне нужно инициализировать ссылку на пустой контейнер STL (точнее, std::set
).
Пытаться:
typedef std::set<bozo *> bozo_set;
class BozoClass { public: BozoClass(): bozosetref(bozo_set()) {} }
получат ошибки компилятора, аналогичные:
bozo.cc:104: error: invalid initialization of non-const reference of type ‘bozo_set& from a temporary of type ‘bozo_set
(Только боковое примечание: это не спрашивает, нужно ли мне или нет использовать typedef
для этого или нет. Я комментирую это, но на самом деле это не настоящий вопрос.)
EDIT: Поскольку было много комментариев об этом, точка ссылки на это заключается в том, чтобы позволить внешним классам изменять элементы bozo
этого набора, вместо того, чтобы иметь тонну ненужных методов в BozoClass
для управления множеством.
Проблема, с которой вы сталкиваетесь, на самом деле хорошо описывается ошибкой компилятора:
недействительная инициализация неконстантной ссылки типа ‘bozo_set & from временного типа’ bozo_set
Компилятор говорит вам, что вы пытаетесь использовать ссылку на временное. Вы не можете этого сделать, потому что вещь, на которую вы ссылаетесь, является временной. Другими словами, он немедленно прекратит свое существование. Временное bozo_set
– это bozo_set
вы bozo_set
здесь:
bozosetref(bozo_set())
^^^^^^^^^^
Как только при выражении bozosetref(bozo_set())
закончит выполнение, set
, set
в bozo_set()
будет уничтожен.
Предположительно, bozosetref
является переменной-членом типа set<bozo*>&
.
Мне кажется, что BozoClass
предназначен для того, чтобы владеть set
который вы пытаетесь ссылаться. Это нормально, но, как вы обычно это делаете, не ссылаясь на set
, а просто создавая экземпляр:
class BozoClass
{
public:
BozoClass() {}
private:
set<bozo*> mBozos;
};
Теперь mBozos
не является ссылкой на set
, а сам set
.
Затем вы можете предоставить ссылку на него клиентам BozoClass
через аксессуар:
class BozoClass
{
public:
// ...
set<bozo*>& GetBozos() { return mBozos; }
};
Клиенты могут, в свою очередь, использовать и изменять set
непосредственно через этот аксессор:
int main()
{
BozoClass bc;
bc.GetBozos().insert (new bozo); // or something
}
- На самом деле, вы можете, но не должны этого делать. Поскольку сам набор не был присвоен переменной, на нем ничего не “держится”. Ссылка, которую вы сделали с ней, становится недействительной.
#include <set>
struct Class {
Class() : set(), setref(set) {}
std::set<void *> set;
std::set<void *> &setref;
};
Вы не можете передавать ссылки на объекты non const.
В вашем случае, если такая вещь будет разрешена, вы получите ссылку на уже удаленный временный экземпляр bozo_set в своем классе, но не ссылку на пустой набор.