Как инициализировать ссылку на пустой контейнер STL в конструкторе?

Вопрос:

Вопрос в значительной степени говорит обо всем этом. Мне нужно инициализировать ссылку на пустой контейнер 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
}

  • На самом деле, вы можете, но не должны этого делать. Поскольку сам набор не был присвоен переменной, на нем ничего не «держится». Ссылка, которую вы сделали с ней, становится недействительной.
Ответ №1
#include <set>

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

std::set<void *> set;
std::set<void *> &setref;
};
Ответ №2

Вы не можете передавать ссылки на объекты non const.
В вашем случае, если такая вещь будет разрешена, вы получите ссылку на уже удаленный временный экземпляр bozo_set в своем классе, но не ссылку на пустой набор.

Оцените статью
TechArks.Ru
Добавить комментарий