Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:
function foo() {
var result;
$.ajax({
url: '...',
success: function(response) {
myCallback(response);
}
});
return result;
}
function myCallback(response) {
// Does something.
}
#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
. Этот тип будет реализовывать метод emplace()
, который также будет реализовывать конструкцию на месте.
#include <optional>
int main() {
std::optional<int> x;
x.emplace(3);
}
В версии 1.56 .0, boost::optional
также будет реализовывать метод emplace()
, о котором я говорил для std :: optional. Итак, давайте посмотрим, что:
#include <boost/optional.hpp>
int main() {
boost::optional<int> x;
x.emplace(3);
}
Как только вы это знаете, вы можете создать обычную ссылку:
optional<Foo> optFoo = ....;
Foo &foo = *optFoo;
foo.x = 3;
foofun(foo);
foo = Foo();
Документированный интерфейс не поддерживает это.
Однако, если вы знаете, что никто не расширяет 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 напрямую.