Skip to content

Commit c3db48a

Browse files
committed
fix continuations with lvalue callables
1 parent a78b638 commit c3db48a

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

libs/internal/include/launchdarkly/async/promise.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Continuation<R(Args...)> {
4343
template <typename F>
4444
struct Impl : Base {
4545
F f;
46-
Impl(F&& f) : f(std::move(f)) {}
46+
Impl(F f) : f(std::move(f)) {}
4747
R call(Args... args) override { return f(std::forward<Args>(args)...); }
4848
};
4949

@@ -56,7 +56,7 @@ class Continuation<R(Args...)> {
5656
// then moves it into Impl<F> so Continuation itself owns the callable.
5757
template <typename F>
5858
Continuation(F&& f)
59-
: impl_(std::make_unique<Impl<F>>(std::forward<F>(f))) {}
59+
: impl_(std::make_unique<Impl<std::decay_t<F>>>(std::forward<F>(f))) {}
6060
Continuation(Continuation&&) = default;
6161
Continuation& operator=(Continuation&&) = default;
6262

libs/internal/tests/promise_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,14 @@ TEST(Promise, ExpectedFailure) {
307307
EXPECT_EQ(result->error(), "timed out");
308308
}
309309

310+
// Verifies that a Continuation can be constructed from an lvalue callable
311+
// (named lambda), not just from a temporary.
312+
TEST(Promise, LvalueLambdaContinuation) {
313+
auto fn = [](int x) { return x * 2; };
314+
Continuation<int(int)> c(fn);
315+
EXPECT_EQ(c(21), 42);
316+
}
317+
310318
TEST(WhenAll, NoFutures) {
311319
Future<std::monostate> result = WhenAll();
312320
EXPECT_TRUE(result.IsFinished());

0 commit comments

Comments
 (0)