ошибка, связанная с привязкой неконстантного lvalue к rvalue в конструкторе - PullRequest
0 голосов
/ 06 июля 2019

Для следующих определений шаблона в моем заголовочном файле,

template<typename T>
    class node{
        private:
            T& data;
            shared_ptr<node<T>>& next;

        public:
            node(T&);
            ~node();
    };

template<typename X>
  class list{
        private:
            shared_ptr<X>& head;
        public:
            list();
            ~list();
     };

и следующая строка кода в main():

list<node<string>>menu;

Я получаю следующую ошибку компиляции для инициализации члена shared_ptr<X>& head внутри конструктора:

template<typename X>
list<X>::list():head(make_shared<X>(NULL)){
}

error: cannot bind non-const lvalue reference of type "std::shared_ptr<node<std::basic_string<char> > >" to an rvalue of type "std::shared_ptr<node<std::basic_string<char> > >"
 list<X>::list():head(make_shared<X>(NULL)){
                                          ^

Насколько я понимаю, ошибка связана с попыткой связать значение r, сгенерированное вызовом make_shared(), с lvalue shared_ptr<X>& head.

Как я могу устранить эту ошибку?

1 Ответ

2 голосов
/ 06 июля 2019

Проблема в следующем, вы создаете временную

make_shared<X>(NULL)

, который умрет после выполнения строки, и ссылка в вашем классе будет зависать (т.е. ссылаться на что-то, что было уничтожено), если вы попытаетесь получить доступ к ссылке, вы окажетесь на неопределенной территории поведения (ваша программа может аварийно завершить работу или еще хуже в поврежденном состоянии). Способ исправить это - не использовать ссылки на shared_ptr, а непосредственно shared_ptr во всех ваших классах, что намного безопаснее.

Во-вторых, вы можете использовать nullptr вместо NULL

Наконец, я думаю, что вы неправильно понимаете, что должны делать ссылки: они не о владении ресурсом, а просто разрешают доступ к ресурсу, когда у вас есть ссылка на что-то, вы должны быть уверены, что кто-то еще поддерживать этот ресурс живым до тех пор, пока вы хотите получить доступ к ресурсу по ссылке (есть исключение: продление срока действия через локальную ссылку const, см. https://blog.galowicz.de/2016/03/23/const_reference_to_temporary_object/).

...