Ссылочная инициализация в C ++ - PullRequest
9 голосов
/ 23 февраля 2010

Может кто-нибудь объяснить мне, почему есть разница между этими двумя утверждениями?

class A{};

const A& a = A();         // correct 

A& b = A();               // wrong

Это говорит неверная инициализация неконстантной ссылки типа A& из временного типа A

Почему const имеет значение здесь?

Ответы [ 5 ]

14 голосов
/ 23 февраля 2010

Неконстантные ссылки должны быть инициализированы l-значениями. Если бы вы могли инициализировать их с временными файлами, что бы вы сделали?

int& foo = 5;
foo = 6; // ?!
Ссылки

const имеют специальное свойство, которое продлевает жизнь рефери, и, поскольку они const, нет никакой возможности попытаться изменить что-то, что не помещается в памяти. Например:

const int& foo = 5;
foo = 6; // not allowed, because foo is const.

Помните, что ссылки на самом деле должны ссылаться на что-то, а не только на временные переменные. Например, допустимо следующее:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);
3 голосов
/ 23 февраля 2010

Терминология по этому вопросу немного сбивает с толку; Вы можете исследовать их немного дальше. Вот краткий ответ:

Вы назначаете временный объект (результат вызова конструктора класса) переменной. Временный объект - это R-значение. Вы не можете присвоить R-значение неконстантной ссылке.

Вам разрешено присваивать R-значение константной ссылке, хотя обоснование его разрешения довольно неясно.

1 голос
/ 23 февраля 2010

В языке C ++ запрещается прикреплять неконстантную ссылку к r-значению, в то время как совершенно нормально присоединять константную ссылку к r-значению. Например, это законно

const int& r = 5;

пока это не

int &r = 5; // ERROR

Временный объект типа A, возвращаемый выражением A(), является значением r, поэтому приведенное выше правило применимо и в вашем случае.

1 голос
/ 23 февраля 2010

Для временного значения / rvalue вы можете иметь только константную ссылку.

Вы можете иметь неконстантную ссылку на не временное значение / lvalue.

A a;
A& b = a;

Я полагаю, что причина состоит в том, чтобы усилить тот факт, что значение является временным, поскольку нет никакой ценности в способности изменить то, что собирается исчезнуть на мгновение.

0 голосов
/ 03 октября 2016

Потому что стандарт гласит:

§8.5.3.5 ... В противном случае ссылка должна быть ссылкой lvalue на энергонезависимый тип const ...

Однако, если вы очень сильно этого хотите, вы можете получить:

#include <iostream>
int main()
{
  const int & cr=5;
  int & r=const_cast<int &>(cr);
  r=6;
  std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64

Но имейте в виду, что предполагаемая константа cr больше не является константой, и вы подвергаетесь неопределенному поведению. (§1.9 (4))

Как следует из приведенного выше кода, нет технической причины для различия. Скорее, у дизайнеров были кошмары о том, что пользователи будут делать с неконстантными ссылками на временные ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...