Привязка временных файлов к неконстантным ссылкам в случае исключений

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

ДЕЛО 1:-

Например:-

class Simple{
    public: 
       int i;
       Simple(Simple &f)
       {
         i = f.i + 1;
       }
       Simple(int j)
       {
         i = j;
       }
  };

int main()
{
   Simple f1 = Simple(2);   // error no matching call fruit::fruit(fruit)...
   return 0;
}

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

СЛУЧАЙ 2: -

try
{
 throw e;
}
catch ( exception& e )
{
}

Я узнал, что, когда мы генерируем исключение, то, что действительно передается для catch, является копией исходного исключения, то есть создается временное значение для брошенного объекта, а затем оно будет передано в предложение catch.

Уловка перехватывает это исключение по неконстантной ссылке. Это контрастирует с тем, что я показал в СЛУЧАЕ 1.

Итак, мои вопросы: -

1) Существуют ли конкретные сценарии, в которых разрешена временная привязка к неконстантной ссылке.

2) Если есть, то какие факторы учитываются при разрешении этих исключений.


person ravi    schedule 07.11.2014    source источник
comment
Он имел в виду не разрешено, как показывает пример кода.   -  person Mike C    schedule 07.11.2014


Ответы (1)


Существуют ли конкретные сценарии, в которых разрешена временная привязка к неконстантной ссылке.

Для lvalue-ссылок (то есть типа T&) нет. Вы не можете привязать временное значение к неконстантной lvalue-ссылке, потому что нет особого смысла изменять, скажем, литерал типа 42. Они могут связываться с const lvalue-ссылками, потому что тогда было дано обещание не изменять объект, к которому привязана ссылка.

Фактически они могут связываться с rvalue -references ( T&&), но это не имеет отношения к этой теме.

Если есть, то какие факторы принимаются во внимание при разрешении этих исключений.

Верно, что временные не могут быть привязаны к неконстантным lvalue-ссылкам, но есть определенные условия для объектов исключений:

Взято из стандарта C ++ 11 (ближайший проект n3337):

§15.1 / 3 throw-expression инициализирует временный объект, называемый объектом исключения, тип которого определяется удалением любых cv-квалификаторов верхнего уровня из статического тип операнда выброса и изменение типа с «массив T» или «функция, возвращающая T» на «указатель на T» или «указатель на функцию, возвращающую T», соответственно. Временное значение имеет l-значение и используется для инициализации переменной, указанной в соответствующем обработчике (15.3). [..]

курсив мой

cppreference упрощает это до:

В отличие от других временных объектов, объект исключения считается аргументом lvalue при инициализации параметров предложения catch, поэтому он может быть перехвачен ссылкой lvalue, изменен и повторно запущен.

Таким образом, в этом случае вы можете привязать исключение к неконстантной lvalue-ссылке.

person 0x499602D2    schedule 07.11.2014
comment
Да, я знаю, что есть исключение в случае исключения. Но это мой вопрос, на каком основании он был выбран ИЛИ есть ли другие подобные исключения ... - person ravi; 07.11.2014
comment
@ravi Причина, по которой это положение было сделано, заключалась в том, чтобы разрешить изменение и повторное создание исключения, как в нем говорится. Я не знаю других исключений из этого правила. - person 0x499602D2; 07.11.2014
comment
@ravi Решение основной проблемы 1299 похоже, что он может ответить на ваш вопрос. - person ; 07.11.2014
comment
@ 0x499602D2 отличный ответ, я только что подумал об этом, проголосовал за - person vsoftco; 10.03.2015
comment
нет особого смысла изменять, скажем, литерал типа 42. Почему это не применяется, когда 42 выбрасывается как исключение? Я не понимаю, почему имеет смысл изменять литерал (временный, инициализированный значением литерала, я думаю), когда он используется в контексте исключения. - person François Andrieux; 19.12.2019
comment
@ FrançoisAndrieux Поскольку вы не можете перехватывать исключения по ссылке rvalue, я понимаю, что это необходимо для предотвращения чрезмерного копирования, поскольку throw X() - наиболее распространенный способ создания исключений. - person 0x499602D2; 19.12.2019