Commit c4629e37 authored by Harris Hancock's avatar Harris Hancock

Fix build error in MSVC

Closes #479.

If T is a template instantiation and `List<T, kind<T>()>` is the return or
parameter type of a function (notably get, set, init, adopt, and disown
functions) defined out-of-line from its definition, MSVC fails to match
the definition with its declaration. This seems to be another consequence
of poor expression SFINAE / constexpr support.

An easy workaround is to avoid using kind<T>() and instead manually
instantiate Kind_<T>, as in lite mode. When I converted Kind_<T> to use
VoidSfinae, I had thought this solved the problem, but clearly there are
still edge cases.
parent 02b7f5ad
......@@ -161,15 +161,19 @@ inline constexpr Kind kind() {
return k;
}
#if CAPNP_LITE
#if _MSC_VER
#define CAPNP_KIND(T) ::capnp::_::Kind_<T>::kind
// Avoid constexpr methods in lite mode (MSVC is bad at constexpr).
// Avoid constexpr methods in MSVC (it remains buggy in many situations).
#else // CAPNP_LITE
#else // _MSC_VER
#define CAPNP_KIND(T) ::capnp::kind<T>()
// Use this macro rather than kind<T>() in any code which must work in lite mode.
// Use this macro rather than kind<T>() in any code which must work in MSVC.
#endif // _MSC_VER, else
#if !CAPNP_LITE
template <typename T, Kind k = kind<T>()>
inline constexpr Style style() {
......@@ -178,7 +182,7 @@ inline constexpr Style style() {
: k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER;
}
#endif // CAPNP_LITE, else
#endif // !CAPNP_LITE
template <typename T, Kind k = CAPNP_KIND(T)>
struct List;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment