Это нужно воспринимать как перемещение. Если unified будет ссылаться на существующий unique, то, при попытке скопировать/переместить этот unified в другой unique будет выброшено исключение.
Здравствуйте, ViTech, Вы писали:
VT>Здравствуйте, vopl, Вы писали:
V>>А посмотри еще на QPointer: V>>
V>>A guarded pointer, QPointer<T>, behaves like a normal C++ pointer T *, except that it is automatically set to 0 when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). T must be a subclass of QObject.
V>>Оно же, чуть ближе Smart observers to use with unique_ptr V>>А? Вместо неявного шаринга использовать такой оповещаемый не-владеющий указатель. Ну и многопоток разруливать не продлением жизни а классически, блокировками.
VT>От оповещающегооповещаемого невладеющего указателя в многопотоке толка мало. Объект может помереть после проверки указателя.
Ну, если так в лоб, неподумавши — конечно, не срастется ничего Предполагается не "проверять-потом-использовать" а "захватывать-использовать-отпускать".
Здравствуйте, ViTech, Вы писали:
VT>Это нужно воспринимать как перемещение. Если unified будет ссылаться на существующий unique, то, при попытке скопировать/переместить этот unified в другой unique будет выброшено исключение.
Ну т.е. вы еще и проверки переносите из compile-time в run-time. Еще один большой жирный "плюс".
Здравствуйте, vopl, Вы писали:
V>>>Оно же, чуть ближе Smart observers to use with unique_ptr V>>>А? Вместо неявного шаринга использовать такой оповещаемый не-владеющий указатель. Ну и многопоток разруливать не продлением жизни а классически, блокировками.
VT>>От оповещающегооповещаемого невладеющего указателя в многопотоке толка мало. Объект может помереть после проверки указателя.
V>Ну, если так в лоб, неподумавши — конечно, не срастется ничего Предполагается не "проверять-потом-использовать" а "захватывать-использовать-отпускать".
Можно, наверное, в контрольном блоке какой-нибудь мьютекс таскать, как вариант реализации, почему нет. Если не ошибаюсь, тоже получается продление жизни объекта, только не за счёт временного захвата владения, а удержания/блокирования владения у самого владельца. И, возможно, стоит ждать в гости deadlock'и . Также, насколько знаю, блокирующим схемам не очень рады task based thread pool, типа Intel TBB.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, ViTech, Вы писали:
VT>>Это нужно воспринимать как перемещение. Если unified будет ссылаться на существующий unique, то, при попытке скопировать/переместить этот unified в другой unique будет выброшено исключение.
S>Ну т.е. вы еще и проверки переносите из compile-time в run-time. Еще один большой жирный "плюс".
Всё что можно проверить в compile-time — проверяется в compile-time. Остальное в run-time.
Здравствуйте, ViTech, Вы писали:
VT>Здравствуйте, so5team, Вы писали:
S>>Скажите, а вы нормальным языком постановку задачи сделать можете? S>>А то фразы вроде "для нормальной поддержки уникального владения (композитной агрегации), чтобы соблюдалась целостность связей" не понятны от слова совсем. S>>Ну и "std::unique_ptr в std::function<void()> не лезет" так же не мешало бы расшифровать. Вы ограничены рамками C++11?
А так не пойдет?
#include <memory>
#include <functional>
#include <iostream>
using namespace std;
void foo( shared_ptr<int> ptr )
{
cout << "foo shared: " << *ptr << endl;
}
void bar( unique_ptr<int>& ptr )
{
cout << "bar unique: " << *ptr << endl;
}
int main()
{
auto s = make_shared<int>( 7 );
function<void()> foo_f = bind( &foo, move( s ) );
foo_f();
auto u = make_unique<int>( 7 );
auto bar_f = bind( &bar, move( u ) );
bar_f();
return 0;
}
Здравствуйте, Igore, Вы писали:
I>А так не пойдет? I>
...
Так пойдет, если нужно сразу вызвать или передать Callable объект в функцию, которая получает такой объект в шаблонном параметре (например, std::thread::thread()). Но в один контейнер (std::queue, std::vector и т.п.) нельзя положить разные bind или lambda (даже с одинаковыми проблема). Такое может понадобиться, если требуется организовать очередь команд. std::function выполняет роль универсального контейнера для различных типов "команд": bind, lambda и т.п. И далее std::function с разными командами можно складывать в один контейнер (std::queue, std::vector).
Но: "std::function satisfies the requirements of CopyConstructible and CopyAssignable.". Т.е. она может копироваться, а заодно и все связанные аргументы, среди которых могут быть и некопируемые объекты. Хотя с большой вероятностью "команды" в коде будут только перемещаться, а не копироваться, но при компиляции std::function будет собираться её конструктор копирования, который будет копировать Callable объект, который некопируемый . Это одна из загвоздок, которая склонила чашу весов в сторону отдельной реализации указателей upl, основанной не на использовании std::shared_ptr/weak_ptr в качестве backend'а. Но я нашёл другой костыль для обхода этой ситуации, который позволит вернуться к реализации с использованием std::shared_ptr/weak_ptr. При этом придётся пожертвовать частью возможностей указателей upl, но реализация будет легче, и не надо будет изобретать велосипед для неё.