Нет, кроме классов, использующих строковый поток

У меня есть класс с членом std::stringstream:

class Buffer
{
    std::stringstream ss_;
};

Его конструктор перемещения

Buffer::Buffer(Buffer&& buf)
: ss_(std::move(buf.ss_))
{
}

Я подозреваю, что операция перемещения не вызовет исключение, и из-за этого конструктор перемещения может быть noexcept. Итак, мои вопросы:

  1. Как определить, объявлена ​​ли функция из STL noexcept, например std::stringstream::str?
  2. Если замена или перемещение stringstream не было noexcept, могу ли я объявить Buffer членов noexcept и получить вызов std::unexpected(), если stringstream выдает исключение? Из того, что я могу найти, это было бы так.
  3. Есть ли способ обойти проблему, например, альтернативный контейнер, в который можно записать с помощью операторов потока, и это noexcept?
  4. Если я последую этим предложениям и просто не буду использовать noexcept, могу ли я ожидать, что компилятор определит, могут ли контейнеры STL использовать перемещение или вместо этого нужно сделать копию?

person hochl    schedule 31.01.2017    source источник


Ответы (1)


  1. Используйте оператор noexcept:

    noexcept(std::declval<std::stringstream>().str())
    
  2. да.

  3. Память и ввод-вывод не являются неограниченными ресурсами. Сразу приходят на ум две стратегии обработки недоступности ресурсов: создать исключение или завершить приложение.
  4. Да, специальные функции-члены по умолчанию имеют неявную nothrow(true) спецификацию исключений при выполнении условий, то есть соответствующие специальные функции-члены базовых классов и членов также должны быть nothrow(true).
person Maxim Egorushkin    schedule 31.01.2017