Есть ли законный способ перейти от gsl :: not_null & lt; T & gt ;?

Библиотека поддержки руководства введены not_null<T> кто имеет целью принудительное применение инварианта для типов, похожих на указатели, а также для интеллектуальных указателей. тем не мение это известная проблема тот not_null<unique_ptr<T>> не работает

Насколько я понимаю, причина в том, что unique_ptr<T> не копируемо и not_null<T> не имеет конструктора, который переместился бы из его T. not_null<T> не может быть конструируемым по умолчанию, потому что это нарушит его инвариант. Даже если бы мы могли построить not_null<unique_ptr<T>>было бы невозможно осмысленно достичь unique_ptr внутри, потому что мы не могли скопировать unique_ptr и двигаясь это уйдет not_null<T> с nullptr. Это похоже на идеальную ловушку.

Я утверждал, что мы могли бы на законных основаниях перейти от not_null<T> объект в определенном контексте: непосредственно перед тем, как он выходит из области видимости. Другими словами, выход из него должен быть последним доступом перед уничтожением. Таким образом, объект с нарушенным инвариантом не будет заметен для остальной части программы. (Это было бы заметно для not_nullтолько собственный код.)

В следующих примерах предположим, что мы можем перейти от not_null<T>,

not_null<unique_ptr<int>> f()
{
return make_unique<int>(1);
}

void g(not_null<unique_ptr<int>> p)
{
...
}

void h()
{
auto p = f();
g(make_unique<int>(2));
}
  1. Правильно ли мое предположение, что состояние not_null<unique_ptr<int>> вернувшийся из f () не мог просочиться после перехода от него (только для примера)?

  2. Правильно ли мое предположение, что состояние not_null<unique_ptr<int>> переданный в g () не может течь после перехода от него (только для примера)?

  3. Можно ли разрешить этот особый вид перемещения, одновременно запрещая общий случай перемещения в C ++ 14/17?

1

Решение

1&2: Игнорирование того факта, что elision сделает вопрос спорным на любом компиляторе, стоит использовать, да. Также игнорируя тот факт, что unique_ptr не могу «Утечка».

3: Нет.

Это было предметом некоторых дискуссий в списке рассылки предложений ISO C ++. Общая концепция — это «разрушительное движение», когда действие по перемещению от объекта и его уничтожению выполняется в одном вызове. Но это должно быть языковой особенностью; в C ++ 14 нет способа определить, вызывается ли конструктор / присваивание move так, что данный объект наверняка будет уничтожен.

0

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

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