I’m writing template quad matrix in C++ and want to search determinant using first row, but it generated C1202 error (C1202 recursive type or function dependency context too complex).
Don’t know what compiler i use, but i compile this on windows with VS2017 community.. It will be nice if you explain me how to check it too.
#include <iostream>
#include <array>
#include <MatrixNxN.h>
int main()
{
MatrixNxN<float, 4> m1(
{
3, -3, -5, 8,
-3, 2, 4, -6,
2, -5, -7, 5,
-4, 3, 5, -6,
});
auto res = m1.GetDeterminant();
std::system("pause");
}
template<typename _Type, size_t _Size>
_Type MatrixNxN<_Type, _Size>::GetDeterminant()
{
if (_Size == 2)
return operator[](0) * operator[](3) - operator[](2) * operator[](1);
_Type result = 0;
for (size_t i = 0; i < _Size; i++)
{
if (i & 0)
result += operator[](i) * GetMinor(i, 0).GetDeterminant();
else
result -= operator[](i) * GetMinor(i, 0).GetDeterminant();
}
return result;
}
template<typename _Type, size_t _Size>
MatrixNxN<_Type, _Size - 1> MatrixNxN<_Type, _Size>::GetMinor(size_t row, size_t col) const
{
size_t index = 0;
MatrixNxN<_Type, _Size - 1> result;
for (size_t i = 0; i < _Size; i++)
{
if (i == col)
continue;
for (size_t j = 0; j < _Size; j++)
{
if (j == row)
continue;
result[index++] = GetElement(j, i);
}
}
return result;
}
Output log:
1> 1>------ Build started: Project: Matricies, Configuration: Debug Win32 ------
1>main.cpp
1>d:projectsmatriciesresheadersmatrixnxn.h(9): warning C4200: nonstandard extension used: zero-sized array in struct/union
1>d:projectsmatriciesresheadersmatrixnxn.h(9): note: This member will be ignored by a defaulted constructor or copy/move assignment operator
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,0>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,1>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation '_Type MatrixNxN<_Type,1>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,1>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,2>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation '_Type MatrixNxN<_Type,2>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,2>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,3>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation '_Type MatrixNxN<_Type,3>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,3>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,4>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesressrcmain.cpp(14): note: see reference to function template instantiation '_Type MatrixNxN<_Type,4>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesressrcmain.cpp(13): note: see reference to class template instantiation 'MatrixNxN<float,4>' being compiled
1>d:projectsmatriciesresheadersmatrixnxn.h(9): warning C4307: '*': integral constant overflow
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,4294967295>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,0>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation '_Type MatrixNxN<_Type,0>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to class template instantiation 'MatrixNxN<_Type,0>' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(181): note: while compiling class template member function '_Type MatrixNxN<_Type,1>::GetDeterminant(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation '_Type MatrixNxN<_Type,1>::GetDeterminant(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(17): warning C4307: '*': integral constant overflow
1>d:projectsmatriciesresheadersmatrixnxn.h(48): warning C4307: '*': integral constant overflow
1>d:projectsmatriciesresheadersmatrixnxn.h(47): note: while compiling class template member function 'MatrixNxN<_Type,4294967295>::MatrixNxN(const MatrixNxN<_Type,4294967295> &)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(213): note: see reference to function template instantiation 'MatrixNxN<_Type,4294967295>::MatrixNxN(const MatrixNxN<_Type,4294967295> &)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(199): note: while compiling class template member function 'MatrixNxN<_Type,4294967295> MatrixNxN<_Type,0>::GetMinor(size_t,size_t) const'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation 'MatrixNxN<_Type,4294967295> MatrixNxN<_Type,0>::GetMinor(size_t,size_t) const' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(199): note: while compiling class template member function 'MatrixNxN<_Type,0> MatrixNxN<_Type,1>::GetMinor(size_t,size_t) const'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation 'MatrixNxN<_Type,0> MatrixNxN<_Type,1>::GetMinor(size_t,size_t) const' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(199): note: while compiling class template member function 'MatrixNxN<_Type,1> MatrixNxN<_Type,2>::GetMinor(size_t,size_t) const'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation 'MatrixNxN<_Type,1> MatrixNxN<_Type,2>::GetMinor(size_t,size_t) const' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(199): note: while compiling class template member function 'MatrixNxN<_Type,2> MatrixNxN<_Type,3>::GetMinor(size_t,size_t) const'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation 'MatrixNxN<_Type,2> MatrixNxN<_Type,3>::GetMinor(size_t,size_t) const' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(199): note: while compiling class template member function 'MatrixNxN<_Type,3> MatrixNxN<_Type,4>::GetMinor(size_t,size_t) const'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(189): note: see reference to function template instantiation 'MatrixNxN<_Type,3> MatrixNxN<_Type,4>::GetMinor(size_t,size_t) const' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(54): note: while compiling class template member function 'MatrixNxN<float,4>::MatrixNxN(std::initializer_list<_Type>)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesressrcmain.cpp(7): note: see reference to function template instantiation 'MatrixNxN<float,4>::MatrixNxN(std::initializer_list<_Type>)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(41): warning C4307: '*': integral constant overflow
1>d:projectsmatriciesresheadersmatrixnxn.h(40): note: while compiling class template member function 'MatrixNxN<_Type,4294967295>::MatrixNxN(void)'
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesresheadersmatrixnxn.h(201): note: see reference to function template instantiation 'MatrixNxN<_Type,4294967295>::MatrixNxN(void)' being compiled
1> with
1> [
1> _Type=float
1> ]
1>d:projectsmatriciesressrcmain.cpp(17): fatal error C1202: recursive type or function dependency context too complex
1>MatrixNxN.cpp
1>Generating Code...
1>Done building project "Matricies.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I expected this code will work correct, but something go wrong for now :C
We are not done yet…
I figured in «/fpermissive-» the root cause of compilation failure is an issue determining the field count. With the following patches (workarrounds?) it works:
template <class T, std::size_t Begin, std::size_t Middle>
constexpr std::size_t detect_fields_count(size_t_<Begin>, size_t_<Middle>, int) noexcept {
constexpr std::size_t next_v = (Begin + Middle) / 2;
using next_t = size_t_<next_v>;
return detail::detect_fields_count<T, Begin, next_v>(size_t_<Begin>{}, next_t{}, 1L);
}
template <class T, std::size_t N>
constexpr std::size_t detect_fields_count_greedy(size_t_<N>, size_t_<N>) noexcept {
return detail::detect_fields_count_greedy_remember<T, N>(size_t_<N>{}, 1L);
}
-> Notice the explicit template argumrents for std::size_t, otherwise it wouldnt select the
» -> enable_if_constructible_helper_t<T, N>» versions. IMO it looks like a compiler bug and there is an issue extracting «N» from size_t_<N>
.
Visual Studio 2017 15.9.9 + workarround -> /std:c++latest
std::array<uint8_t, 255> -> OK
std::array<uint8_t, 256> -> C1202
Visual Studio 2017 15.9.9 + workarround -> /std:c++latest /permissive-
std::array<uint8_t, 255> -> OK
std::array<uint8_t, 512> -> OK
std::array<uint8_t, 513> -> C1202
Visual Studio 2019 RC + workarround -> /std:c++latest /permissive-
std::array<uint8_t, 255> -> OK
std::array<uint8_t, 512> -> OK
std::array<uint8_t, 513> -> C1202
Permalink
Cannot retrieve contributors at this time
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Fatal Error C1202 |
Fatal Error C1202 |
11/04/2016 |
C1202 |
C1202 |
c859adb8-17a7-4fa1-a1f3-5820b7bf3849 |
recursive type or function dependency context too complex
A template definition was recursive or exceeded complexity limits.
Examples
The following sample generates C1202.
// C1202.cpp // processor: x86 IPF template<int n> class Factorial : public Factorial<n-1> { // C1202 public: operator int () { return Factorial <n-1>::operator int () * n; } }; Factorial<7> facSeven;
Possible resolution.
// C1202b.cpp // compile with: /c template<int n> class Factorial : public Factorial<n-1> { public: operator int () { return Factorial <n-1>::operator int () * n; } }; template <> class Factorial<0> { public: operator int () { return 1; } }; Factorial<7> facSeven;