Есть ли C ++ 14 / boost эквивалент std :: in_place для `optional`? [Дубликат]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
7
задан MK. 7 August 2014 в 15:54
поделиться

3 ответа

boost :: optional

#include <boost/optional.hpp>

int main() {
    boost::optional<int> x;
    x = boost::in_place(3);
}

Мы также можем показать (через код), что это создание объекта на месте, сделав Foo наследованием от boost::noncopyable:

#include <boost/optional.hpp>
#include <boost/noncopyable.hpp>

class Foo : boost::noncopyable {
    public:
        Foo(int one, int two) {}
};


int main() {
    boost::optional<Foo> x;
    x = boost::in_place(3, 4);
}

std :: optional (в конце концов ...)

В конце концов мы получим доступ к std::optional. Этот тип будет реализовывать метод emplace(), который также будет реализовывать конструкцию на месте.

#include <optional>

int main() {
    std::optional<int> x;
    x.emplace(3);
}

boost :: optional (soon ...)

В версии 1.56 .0, boost::optional также будет реализовывать метод emplace(), о котором я говорил для std :: optional. Итак, давайте посмотрим, что:

#include <boost/optional.hpp>

int main() {
    boost::optional<int> x;
    x.emplace(3);
}
7
ответ дан Drew Dormann 1 September 2018 в 05:17
поделиться

Как только вы это знаете, вы можете создать обычную ссылку:

optional<Foo> optFoo = ....;
Foo &foo = *optFoo;
foo.x = 3;
foofun(foo);
foo = Foo();
0
ответ дан Sebastian Mach 1 September 2018 в 05:17
поделиться

Документированный интерфейс не поддерживает это.

Однако, если вы знаете, что никто не расширяет boost::optional, я считаю, что это может быть технически обоснованным:

template<typename T, typename... Us>
void emplace_replace( boost::optional<T>& target, Us&&... us ) {
  target.~boost::optional<T>();
  try {
    new (&target) boost::optional<T>( boost::in_place( std::forward<Us>(us)...) );
  } catch(...) {
    new (&target) boost::optional<T>();
    throw;
  }
}

мы уничтожаем target, а затем реконструируем новый boost::optional<T> на своем месте с построением на месте. Конструкция try - catch должна быть большей throw s во время строительства безопасной: если она выбрасывается, вы получаете пустую optional.

Это, естественно, ведет себя иначе, чем operator= Ожидается.


В 1.55 (и, возможно, раньше?) есть недокументированный operator=, который принимает Expr, который поддерживает boost::in_place и boost::in_place<T>. См. Ответ @ sharth для подробного использования.

Мое быстрое чтение указывает, что набранная фабрика inplace с помощью этого метода может иметь недостаточную защиту:

boost::optional<int> test;
// test = boost::in_place<double>( 3 ); // <-- very dangerous
test = boost::in_place( 3 ); // safe
test = boost::in_place( 3.0 ); // safe

Если тип передается непосредственно in_place<?>, он может генерировать typed_in_place_factory, которые являются опасными (они делают переданный тип и не проверяют его совместимость). Поэтому не передавайте никакие типы в boost::in_place.

Это (от чтения источника) делает что-то похожее на мой код destroy / restore, за исключением того, что он делает это без разрушения всего optional и просто разрушает сохраненные данные и делают его неинициализированным.


В boost 1.56b1 в boost::optional добавлено emplace . Он делает что-то похожее на обе вышеупомянутые операции. (через @AkiraTakahashi)


std::optional предложения, которые я видел, включили функцию-член .emplace( Us&&... ), которая поддерживает замену emplace напрямую.

3
ответ дан Yakk - Adam Nevraumont 1 September 2018 в 05:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: