Может ли этот метод когда-либо генерировать исключение?

Учитывать:

template <typename T>
struct S
{
    auto Value() const
    {
        return value;
    }

    T value;
};

Может ли Value() когда-нибудь вызвать исключение? Почему или почему нет? Если нет, то можно ли пометить этот метод как noexcept?

Чего я принципиально не понимаю, так это того, может ли return value; когда-либо вызывать исключение.

Вы возвращаете значение, а это означает, что значение необходимо скопировать. Если у T есть конструктор копирования, он может вызвать исключение.

Some programmer dude 17.04.2024 08:19

Как с этим справиться - написать noexcept(std::is_nothrow_copy_constructible_v<T>).

Passer By 17.04.2024 08:21

@Someprogrammerdude, но сам вызов Value никогда не приводит к копированию, верно?

Honey 17.04.2024 08:21

Возврат @Honey по значению приводит к копии.

wohlstad 17.04.2024 08:22

@PasserBy это именно мое замешательство. Вызов Value сам по себе не приводит к копированию. Так зачем мне проверять is_nothrow_copy_constructible_v?

Honey 17.04.2024 08:22

@wohlstad, что если произойдет копирование?

Honey 17.04.2024 08:23

«Что, если есть исключение копирования» в этом случае не будет, а в тех случаях, когда это произойдет, вы будете двигаться (за исключением некоторых странностей до C++20).

Passer By 17.04.2024 08:25

@Дорогая, содержимое члена value все равно придется скопировать (или переместить) в целевой объект, который вызвал Value(). Это будет сделано с помощью конструктора, который может выдавать исключение.

wohlstad 17.04.2024 08:26

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

Passer By 17.04.2024 08:28
godbolt.org/z/PxWKMMd8b
joergbrech 17.04.2024 08:37

В более общем плане: не тратьте время, пытаясь разобраться в таких вещах, как noexcept, если у вас нет для этого причины. Как видите, это довольно подвержено ошибкам, и компилятор не может это проверить (в отличие, скажем, от override). И в тех случаях, когда компилятор МОЖЕТ это проверить, он, очевидно, может увидеть это и, возможно, использовать в целях оптимизации, даже если вы этого не указали...

Christian Stieber 17.04.2024 12:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Value() может вызвать исключение, поэтому не следует помечать его как noexcept.

Это может произойти, поскольку Value() возвращает объект T по значению.
Это означает, что будет создана копия, и конструктор копирования T может выдать ошибку. Компилятор сгенерирует инструкции копирования в теле метода.

Копирование-эллия не имеет значения, поскольку value является участником, а не местным или временным.
Но даже если это было актуально, это не меняет этого.
Содержимое члена value в любом случае будет скопировано (или перемещено) в целевой объект, вызвавший метод. Это можно сделать путем выполнения соответствующего конструктора T — копирования или перемещения — или оператора присваивания, который может выдать ошибку.

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

Демо - предоставлено @joergbrech .

пожалуйста, помогите мне понять это. Рассмотрим следующие контексты: auto s = S<ComplexType>{}; Первый контекст таков: auto var = s.Value(); и второй: s.Value(); В обоих случаях простой вызов Value() не вызывает исключения, исключение вызывает оператор присваивания. В случае исключения копирования весь оператор auto var = s.Value(); является причиной исключения, а не s.Value();

Honey 17.04.2024 08:39

@Дорогая, пожалуйста, посмотри добавленную мной демонстрацию Godbolt. В вашем комментарии выше член value нужно будет каким-то образом перевести в var. Как я объяснил, это делается путем выполнения конструктора ComplexType. Даже просто s.Value(); вызывает исключение, как вы можете видеть в демо, поскольку компилятор сгенерирует код для выполнения конструктора.

wohlstad 17.04.2024 08:44

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

Sebastian Redl 17.04.2024 08:50

Другие вопросы по теме