Home > Net >  Why does the compiler issue a template recursion error?
Why does the compiler issue a template recursion error?

Time:07-17

I'm currently trying to deduce a std::tuple type from several std::vectors that are passed as parameters. My code works fine using gcc, but the compilation fails with Visual Studio Professional 2019 with the message "fatal error C1202: recursive type or function dependency context too complex".

It has been mentioned for my previous post (C "fatal error C1202: recursive type or function dependency context too complex" in visual studio, but gcc compiles) that the problem is caused by template recursion as explained in C template compilation error - recursive type or function dependency. However, I don't see where the recursion occurs.

So my questions are:

Why is there an (infinite) recursion? How can it be resolved?

Here is the code (I'm bound to C 11):

#include <tuple>
#include <vector>

template <typename TT,typename Add>
auto addTupBase(TT t,std::vector<Add> a) ->decltype (std::tuple_cat(t,std::make_tuple(a[0])))
{
  return std::tuple_cat(t,std::make_tuple(a[0])) ;
}

template <typename TT,typename Add,typename... Args>
auto addTupBase(TT t,std::vector<Add> a,Args... args)-> decltype(addTupBase(addTupBase(t,a),args...))
{
  return addTupBase(addTupBase(t,a),args...);
}


template <typename T,typename... Args>
auto addTup(std::vector<T> in,Args... args) ->decltype(addTupBase(std::make_tuple(in[0]),args...))
{
  return addTupBase(std::make_tuple(in[0]),args...);
}

int main()
{
  using TupleType = decltype(addTup(std::vector<char>{2},std::vector<int>{5},std::vector<double>{32423}));
  TupleType t;
  std::get<2>(t) = 342.2;
  return 0;
}

CodePudding user response:

MSVC has some conformance issues when running in /permissive mode and "The Microsoft C compiler doesn't currently support binding nondependent names when initially parsing a template. This doesn't conform to section 14.6.3 of the C 11 ISO specification. This can cause overloads declared after the template (but before the template is instantiated) to be seen.".

If you instead use /permissive- "The compiler [...] implements more of the requirements for two-phase name look-up" and will compile your program as-is.

Also note that you aren't actually using C 11. MSVC 19.24 supports C 14 and up.

  • Related