sgorsten / linalg

linalg.h is a single header, public domain, short vector math library for C++
The Unlicense
849 stars 68 forks source link

mul(a,b,c) with visual studio 2017 release candidate #5

Closed melax closed 7 years ago

melax commented 7 years ago

Only hit one snag with visual studio 2017 RC.
With existing projects that worked fine with earlier compiler (20150), I now get the compiler error:

c:\users...\include\linalg.h(301): fatal error C1202: recursive type or function dependency context too complex

which refers to the following line of code:

    template<class T, int M, int N, class... R> auto mul(const mat<T,M,N> & a, R... r) -> decltype(mul(a, mul(r...))) { return mul(a, mul(r...)); }

This routine is typically used in lines of code that multiply 3 matrices together such as:

    float3x3 Iinv = mul(s_orientation_matrix, tensorinv, transpose(s_orientation_matrix));

As a temporary workaround, i just commented out this implementation of mul(...) and replaced it with a specific one takes 3 float3x3s since that's the only use case i need at the moment.

    inline float3x3 mul(const float3x3 &a, const float3x3 &b, const float3x3 &c) { return mul(mul(a, b), c);  }  // VS2017 release candidate failing to compile the multi-arg mul from linalg.h

Sure, that works. However, ideally would rather have a general mul that takes an arbitrary number of matrices of any compatible types. Any ideas? Wait for MS to fix compiler? or is there something that can be reworked within the linalg.h implementation?

note I'm submitting this issue primarily for awareness, this is not an urgent issue for me.

thanks

sgorsten commented 7 years ago

As a quick workaround, you can simply delete the

-> decltype(mul(a, mul(r...)))

clause, which isn't necessary in C++14.

I might go ahead and update the whole library in a bit to rely on C++14 features. Microsoft is claiming that they should have FULL C++98/11/14 compatibility (even two phase lookup!) for the actual release of Visual Studio 2017. GCC and Clang have had it for a couple of years. It's probably time.

melax commented 7 years ago

Yes, tested and it works. Just removing the specification of the return leads to successful compilation for code with both 2015 and 2017. Given the compiler deduces the type anyways, this seems to be an acceptable solution rather than just a 'workaround'. Any reason to not simply close the issue?

sgorsten commented 7 years ago

It's a breaking change for anyone still compiling with a C++11 compiler, which means I should probably bump the major version number, and if I'm going to declare linalg v3.0 and a dependency on C++14, I kinda want to go ahead and update a number of things.

xelatihy commented 7 years ago

One suggestion. You might want to try variadic templates. Worked great on some test code I wrote recently. If you are interested, I can upload a few test cases I wrote on this.

sgorsten commented 7 years ago

Looks like somewhere along the way I added an explicit workaround.