результате чего должен выбраться generated noexcept вместо defined?
template <typename T>
class A
{
T v;
public:
A() = default;
A(const A&) = default;
//A(A&&) = default;
A(A&&) noexcept(false) = default; [1]
A& operator=(const A&) = default;
A& operator=(A&&) = default;
};
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_nothrow_move_constructible<A<std::string>>::value << '\n'; // false
}
так он не генерируется в этом случае
А скажи, какой смысл в move для такого класса, что он будет перемещать?
не понял ответ. У класса один член - std::string. У std::string move-конструктор noexcept. Следовательно если написать в классе A(A&&) = default, то у класса A move-конструктор так же будет noexcept. Теперь я пытаюсь явно переопределить это, используя conditional noexcept(false). И это работает. Но мне не понятно почему. Так как я прочитал, что если они противоречат, то выбор падает в пользу generated noexcept, а generated в свою очередь смотрит на все свои члены и если у всех move-конструктор noexcept, то и у класса будет noexcept.
Оберните код в теги: 3 символа ` до и после кода (в случае одиночной конструкции достаточно 1 ` с обеих сторон). Спасибо!
я просто пытаюсь поглубже понять как это устроено
Вроде noexcept на default вообще вешать нельзя. У меня по крайней мере компайл тайм ошибки были на кланге
можно. я же показал, что вывод false в main
тут может я как-то не правильно трактую слово "contradict" вот в этом тексте (C++ Move Semantics. Nicolai M. Josuttis). When you have a defaulted special member function you can explicitly specify a different noexcept guarantee than the generated one. For example: class C { ... public: C(const C&) noexcept = default; // guarantees not to throw (OK since C++20) C(C&&) noexcept(false) = default; // specifies that it might throw (OK since C++20) ... }; Before C++20, if the generated and specified noexcept condition contradict, the defined function was deleted.
Обсуждают сегодня