From b6746598f0ad8cbcbe0b0da90c035ba5d3f1aab7 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Fri, 18 Nov 2016 17:53:37 -0800 Subject: [PATCH] Use structs rather than type aliases for Unit::Lift and Unit::Drop Summary: VS 2017 RC brings with it fixes for some things and unfortunately, a few known regressions in expression SFINAE. In this case, alias templates with dependent `decltype()` calls are broken, so switch to a templated struct instead. It's the very last issue mentioned in: https://blogs.msdn.microsoft.com/vcblog/2016/06/07/expression-sfinae-improvements-in-vs-2015-update-3/ Reviewed By: yfeldblum Differential Revision: D4199676 fbshipit-source-id: 9ce157cc891182509a30b000de1b509063387244 --- folly/Unit.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/folly/Unit.h b/folly/Unit.h index df99eba2..f1c71618 100644 --- a/folly/Unit.h +++ b/folly/Unit.h @@ -34,10 +34,16 @@ namespace folly { /// possible to construct a value of this type, but it is always the same value /// every time, so it is uninteresting. struct Unit { + // These are structs rather than type aliases because MSVC 2017 RC has + // trouble correctly resolving dependent expressions in type aliases + // in certain very specific contexts, including a couple where this is + // used. See the known issues section here for more info: + // https://blogs.msdn.microsoft.com/vcblog/2016/06/07/expression-sfinae-improvements-in-vs-2015-update-3/ + template - using Lift = std::conditional::value, Unit, T>; + struct Lift : std::conditional::value, Unit, T> {}; template - using Drop = std::conditional::value, void, T>; + struct Drop : std::conditional::value, void, T> {}; bool operator==(const Unit& /*other*/) const { return true; } bool operator!=(const Unit& /*other*/) const { return false; } -- 2.34.1