Исключительная гарантия безопасности и std :: move ()

Во время некоторой реализации я застрял с проблемой гарантии безопасности исключений и std::move(), Я знаю, что ТАК не очень хорошее место, чтобы спросить: «Каково твое мнение?» Boo) вопрос, но здесь я хотел бы убедиться, что мое понимание верно, и после прочтения этого вопроса, возможно, вы сможете направить меня на правильный путь.

Рассмотрим следующий код:

struct Foo {
using Y = std::vector<std::string>;
using X = std::vector<Y>;

void add (Y y) {
src.push_back (std::move (y));      // (1)
src = process (std::move (src));    // (2)
}

private:
X process (X&& vec) {                   // (F)
for (auto& v : vec) {
v.resize (10);                  // (3)
}
return std::move (vec);
}X src;
};

Посмотрите на add() функция-член, если исключение
выбрасывается из (1) и в соответствии с n4296 [vector.modifiers / 1]

Если исключение выдается при вставке одного элемента в конце и T является CopyInsertable или же is_nothrow_move_constructible<T>::value является trueЭффектов нет.

тогда сильная гарантия сохраняется, я прав?

Если мы посмотрим на (2), то здесь также может быть сгенерировано исключение, потому что (3) может вызвать исключение. Поправь меня если я не прав
В этой ситуации (2), если я перееду src к process() функция-член и исключение выдается из process() затем src является
не указано и что означает, что сохраняется только базовая гарантия?

Делать add() функция члена сильная гарантия, я должен изменить
(2) и (F) соответственно:

src = process (src); // (2)
X process (X vec);   // (F)

?

Так что если Foo::src имеет огромное количество элементов, то делает сильный
гарантия связана с меньшей эффективностью (потому что должна быть сделана дополнительная копия)?

Может быть, уровень гарантии должен быть оставлен на усмотрение пользователя класса, сделав его шаблоном класса, похожим на этот:

struct S {};
struct B {};

template <typename T>
struct Boo {
using Y = std::vector<std::string>;
using X = std::vector<Y>;

void add (Y y) {
src.push_back (std::move (y));
src = process_helper (typename std::is_same<T, S>::type {});
}private:
X process_helper (std::true_type) {
return process (src);
}

X process_helper (std::false_type) {
return process (std::move (src));
}

X process (X vec) {
for (auto& v : vec) {
v.resize (10);
}
return std::move (vec);
}

X src;
};

Это хорошая или плохая идея?

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector