Чтение
Энтони Уильямс "Параллелизм C ++ в действии" (1-е издание)
вы можете найти эту реализацию для многопоточного стека:
struct empty_stack: std::exception
{
const char* what() const throw()
{
return "empty stack";
}
};
template<typename T>
class threadsafe_stack
{
private:
std::stack<T> data;
mutable std::mutex m;
public:
threadsafe_stack(){}
threadsafe_stack(const threadsafe_stack& other)
{
std::lock_guard<std::mutex> lock(other.m);
data=other.data;
}
threadsafe_stack& operator=(const threadsafe_stack&) = delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(new_value);
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
std::shared_ptr<T> const res(std::make_shared<T>(data.top()));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value=data.top();
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
Итак, обсуждая возможные реализации, автор предлагает следующую версию для pop ():
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value=data.top();
data.pop();
}
и подчеркивает некоторые предостережения, и одно из этих предостережений заключается в том, что это решение требует, чтобы тип, хранящийся в стеке, был назначаемым.
В то же время он показывает следующий пример использования:
std::vector<int> result;
some_stack.pop(result);
Теперь мое возражение:
по моему мнению, еще одна оговорка:
оператор присваивания типа, хранящегося в стеке безопасного потока, не должен генерировать исключение, как оператор присваивания std :: vector.
Основано ли мое возражение?
Причины моего возражения:
оно вытекает из анализа следующего (не реализованного) решения, предложенного автором:
"вы можете написать возвращающее значение pop (), если возвращаемое по значению не может вызвать исключение, поэтому для типов, хранящихся в стеке, безопасном для потока, требуется не копирующий конструктор копирования или конструктор перемещения" .
Спасибо за ваше время.