From ca0e432d0fbd3140e4eb172641588ffdbe30b439 Mon Sep 17 00:00:00 2001 From: Andrew Krieger Date: Wed, 18 Oct 2017 15:44:01 -0700 Subject: [PATCH] Workaround MSVC bug with referencing template constructors before definition Summary: MSVC has a bug where it is unable to match an out-of-line constructor (and possibly other kind of member) to the definition if it is implicitly referenced before the definition is processed. The guilty method is SemiFuture makeSemiFuture(). Moving it after the constructor definitions resolves the issue. Reviewed By: yfeldblum Differential Revision: D6042277 fbshipit-source-id: 97fe97c0edf3df3d9e3b808968b450c73959b600 --- folly/futures/Future-inl.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index cdd38f7b..c6ea59a8 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -136,10 +136,6 @@ SemiFuture::type> makeSemiFuture(T&& t) { return makeSemiFuture(Try::type>(std::forward(t))); } -inline SemiFuture makeSemiFuture() { - return makeSemiFuture(Unit{}); -} - // makeSemiFutureWith(SemiFuture()) -> SemiFuture template typename std::enable_if< @@ -246,6 +242,12 @@ SemiFuture::~SemiFuture() { detach(); } +// This must be defined after the constructors to avoid a bug in MSVC +// https://connect.microsoft.com/VisualStudio/feedback/details/3142777/out-of-line-constructor-definition-after-implicit-reference-causes-incorrect-c2244 +inline SemiFuture makeSemiFuture() { + return makeSemiFuture(Unit{}); +} + template T& SemiFuture::value() & { throwIfInvalid(); -- 2.34.1