1

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;
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
user16372530
  • 692
  • 2
  • 13
  • The second overload of `addTupBase` is callable with the same parameters as the first overload; `Args...` may be empty. So the function ends up calling itself recursively, or perhaps gets instantiated recursively in order to perform overload resolution. – Igor Tandetnik Jul 17 '22 at 02:17
  • [Fixed](https://godbolt.org/z/eWE7c3KeE) by changing the second overload so that it requires at least three parameters, thus removing the ambiguity. – Igor Tandetnik Jul 17 '22 at 02:20
  • If you open a _Developer Command Prompt_ and run the command `cl`, what does the first line of output from that command say? I'd like to know the exact version of the compiler since you say your bound to C++11. I don't think any VS2019 compiler supports C++11. – Ted Lyngmo Jul 17 '22 at 02:26
  • @IgorTandetnik The problem seems to be [fixed](https://godbolt.org/z/qnjaq4ddo) by just adding `/permissive-` too – Ted Lyngmo Jul 17 '22 at 02:26
  • @IgorTandetnik Changing the second overload resolves the problem. Thank you very much! I thought that the conforming behavior would be that the first overload is used, when the args is empty... – user16372530 Jul 17 '22 at 02:40
  • @TedLyngmo I get the following output on the command prompt: Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28316 for x8 – user16372530 Jul 17 '22 at 02:41

1 Answers1

1

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.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108