std::exchange noexcept
От: _NN_ www.nemerleweb.com
Дата: 04.11.19 07:03
Оценка:
На днях столкнулся с особенностью std::exchange.
Как оказывается функция не является noexcept, а почему использовать её в конструкторе перемещения нельзя.
Очевидно напрашивается написать свой аналог exchange_no_except.

Почему об этом не подумали в стандарте и как пишете вы ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: std::exchange noexcept
От: sergii.p  
Дата: 04.11.19 14:41
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>На днях столкнулся с особенностью std::exchange.

_NN>Как оказывается функция не является noexcept, а почему использовать её в конструкторе перемещения нельзя.

а почему нельзя? Если вы уверены, что функция не бросит исключение, вы её вполне можете использовать в деструкторах, перемещающих конструкторах и пр. не обращая внимание есть ли там noexcept, или нет.

_NN>Очевидно напрашивается написать свой аналог exchange_no_except.


std::swap? Вообще, вопрос звучит так, как будто вам нужен именно swap.

_NN>Почему об этом не подумали в стандарте и как пишете вы ?


наверное потому что std::exchange может внутри делать копирование. И тогда noexcept точно не поставишь. Можно было бы извращаться, написать кучу перегрузок и в каких-то случаях поставить вожделенный noexcept, но подозреваю что не очень то и надо.

std::string some_value, new_value;
auto old_value = std::exchange(some_value, new_value); // вот тут может быть брошено исключение
Re[2]: std::exchange noexcept
От: _NN_ www.nemerleweb.com
Дата: 04.11.19 16:41
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>Здравствуйте, _NN_, Вы писали:


_NN>>На днях столкнулся с особенностью std::exchange.

_NN>>Как оказывается функция не является noexcept, а почему использовать её в конструкторе перемещения нельзя.

SP>а почему нельзя? Если вы уверены, что функция не бросит исключение, вы её вполне можете использовать в деструкторах, перемещающих конструкторах и пр. не обращая внимание есть ли там noexcept, или нет.


Можно то можно но хотелось бы гарантии по строже чем уверенность.
К тому же статические анализатора кода недовольны

_NN>>Очевидно напрашивается написать свой аналог exchange_no_except.


SP>std::swap? Вообще, вопрос звучит так, как будто вам нужен именно swap.


Exhanhe это не Swap. Иначе не делали бы дополнительную функцию.

_NN>>Почему об этом не подумали в стандарте и как пишете вы ?


SP>наверное потому что std::exchange может внутри делать копирование. И тогда noexcept точно не поставишь. Можно было бы извращаться, написать кучу перегрузок и в каких-то случаях поставить вожделенный noexcept, но подозреваю что не очень то и надо.


Может. Я использую exchange для простых типов вроде указателей чтобы сразу и забрать значение и обнулить .



SP>
SP>std::string some_value, new_value;
SP>auto old_value = std::exchange(some_value, new_value); // вот тут может быть брошено исключение
SP>
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: std::exchange noexcept
От: andyp  
Дата: 04.11.19 21:20
Оценка:
Здравствуйте, _NN_, Вы писали:


_NN>Я использую exchange для простых типов вроде указателей чтобы сразу и забрать значение и обнулить .



Забить на анализаторы. Рекомендации лучших собаководов с cppreference

https://en.cppreference.com/w/cpp/language/move_constructor

struct A
{
    std::string s;
    int k;
    A() : s("test"), k(-1) { }
    A(const A& o) : s(o.s), k(o.k) { std::cout << "move failed!\n"; }
    A(A&& o) noexcept :
           s(std::move(o.s)),       // explicit move of a member of class type
           k(std::exchange(o.k, 0)) // explicit move of a member of non-class type
    { }
};
Re: std::exchange noexcept
От: Videoman Россия https://hts.tv/
Дата: 05.11.19 08:30
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Как оказывается функция не является noexcept, а почему использовать её в конструкторе перемещения нельзя.

Можно, так как в конструкторе перемещения аргумент по определению получается по rvalue reference, а единственно место где может возникнуть исключение (конечно при разумной реализации) это:
template<class T, class U = T>
T exchange(T& obj, U&& new_value)
{
    T old_value = std::move(obj);
    obj = std::forward<U>(new_value); // Вот тут может возникнуть исключение только если obj решит копировать new_value, например если std::forward разрешится в const U&.
    return old_value;
}

Но именно в конструкторе перемещения U&& всегда будет rvalue reference, и здесь всегда будет перемещение, без копирования.

_NN>Почему об этом не подумали в стандарте и как пишете вы ?

Скорее всего, как всегда, это очередная попытка сделать универсальный швейцарский нож на все случаи жизни (используемый не только в конструкторе перемещения).
Re[2]: std::exchange noexcept
От: _NN_ www.nemerleweb.com
Дата: 05.11.19 09:32
Оценка:
Здравствуйте, Videoman, Вы писали:

_NN>>Почему об этом не подумали в стандарте и как пишете вы ?

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

Технически можно было бы объявить exchange как noexcept если move + forward тоже noexcept.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.