2

MSVC++ doesn't yet support variadic templates, so its standard library "fakes" these for classes like std::tuple through use of macros. I recently tried compiling one of my projects with the VC11 beta, and got this to show for it:

gtest\gtest.h(9735): error C2977: 'std::tuple' : too many template arguments
c:\program files (x86)\microsoft visual studio 11.0\vc\include\utility(72) : see declaration of 'std::tuple'
gtest\gtest.h(9743): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(14568): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(14568): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14568): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14568): error C2955: 'testing::internal::ParamGeneratorInterface' : use of class template requires template argument list
c:\users\billy\documents\visual studio 2010\projects\instalog\logtests\gtest\gtest.h(10076) : see declaration of 'testing::internal::ParamGeneratorInterface'
gtest\gtest.h(14570): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(14581): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14581): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14586): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14586): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14593): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
c:\users\billy\documents\visual studio 2010\projects\instalog\logtests\gtest\gtest.h(14593) : see reference to class template instantiation 'testing::internal::CartesianProductGenerator9<T1,T2,T3,T4,T5,T6,T7,T8,T9>::Iterator' being compiled
gtest\gtest.h(14593): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14593): error C2955: 'testing::internal::ParamIteratorInterface' : use of class template requires template argument list
c:\users\billy\documents\visual studio 2010\projects\instalog\logtests\gtest\gtest.h(10003) : see declaration of 'testing::internal::ParamIteratorInterface'
gtest\gtest.h(14595): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14595): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14628): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14628): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14670): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14670): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14674): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14674): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14755): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14755): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14807): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(14807): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14807): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14807): error C2955: 'testing::internal::ParamGeneratorInterface' : use of class template requires template argument list
gtest\gtest.h(14809): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(14821): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14821): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14826): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14826): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14833): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
c:\users\billy\documents\visual studio 2010\projects\instalog\logtests\gtest\gtest.h(14833) : see reference to class template instantiation 'testing::internal::CartesianProductGenerator10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::Iterator' being compiled
gtest\gtest.h(14833): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14833): error C2955: 'testing::internal::ParamIteratorInterface' : use of class template requires template argument list
gtest\gtest.h(14835): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14835): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14871): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14871): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14917): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14917): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(14921): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(14921): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(15007): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(15007): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(15289): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(15289): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(15289): error C2955: 'std::tuple' : use of class template requires template argument list
gtest\gtest.h(15333): error C2977: 'std::tuple' : too many template arguments
gtest\gtest.h(15333): error C3203: 'tuple' : unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
gtest\gtest.h(15333): error C2955: 'std::tuple' : use of class template requires template argument list

I've heard there's a #define that can be set somewhere to change this setting, but I (for the life of me) can't remember what it is. What is it?

James McNellis
  • 348,265
  • 75
  • 913
  • 977
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

3 Answers3

6

You can define _VARIADIC_MAX to any value between 5 and 10, inclusive.

This, and many other interesting facts about Visual C++ 11, can be found in the MSDN article, "C++11 Features (Modern C++)." This particular macro is discussed in the section entitled "Faux variadics."

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • `MSVC++` is driving me crazy! Where exactly do I need to define `_VARIADIC_MAX`? I am using `CMake` and building `GTest` as an OBJECT (see [here](http://stackoverflow.com/a/12543935/1019491)). – Hindol Sep 23 '12 at 06:48
  • Nevermind, found the [solution](http://code.google.com/p/googletest/issues/detail?id=408) `add_definitions(-D_VARIADIC_MAX=10)`. – Hindol Sep 23 '12 at 06:59
2

Interesting quote from blogs.msdn.com article:

Faux variadics: We've developed a new scheme for simulating variadic templates. Previously in VC9 SP1 and VC10, we repeatedly included subheaders with macros defined differently each time, in order to stamp out overloads for 0, 1, 2, 3, etc. arguments. (For example, included the internal subheader repeatedly, in order to stamp out make_shared(args, args, args).) In VC11, the subheaders are gone. Now we define variadic templates themselves as macros (with lots of backslash-continuations), then expand them with master macros. This internal implementation change has some user-visible effects. First, the code is more maintainable, easier to use (adding subheaders was a fair amount of work), and slightly less hideously unreadable. This is what allowed us to easily implement variadic emplacement, and should make it easier to squash bugs in the future. Second, it's harder to step into with the debugger (sorry!). Third, pair's pair(piecewise_construct_t, tuple, tuple) constructor had "interesting" effects. This requires N^2 overloads (if we support up to 10-tuples, that means 121 overloads, since empty tuples count here too). We initially observed that this (spamming out so many pair-tuple overloads, plus all of the emplacement overloads) consumed a massive amount of memory during compilation, so as a workaround we reduced infinity. In VC9 SP1 and VC10, infinity was 10 (i.e. "variadic" templates supported 0 to 10 arguments inclusive). In the VC11 Developer Preview, infinity is 5 by default. This got our compiler memory consumption back to what it was in VC10. If you need more arguments (e.g. you had code compiling with VC9 SP1 or VC10 that used 6-tuples), there's an escape hatch. You can define _VARIADIC_MAX project-wide between 5 and 10 inclusive (it defaults to 5). Increasing it will make the compiler consume more memory, and may require you to use the /Zm option to reserve more space for PCHes.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

This is fixed in revision 675. See https://code.google.com/p/googletest/source/detail?r=675

Corey Kosak
  • 2,615
  • 17
  • 13
  • +1. Gets fixed just as MSVC++ gets variadic templates :) – Billy ONeal Jan 14 '14 at 04:33
  • Hee hee :-) Well we made sure it builds cleanly on VC 12 too. – Corey Kosak Jan 14 '14 at 15:00
  • BTW if the community has come up with a standard workaround for http://connect.microsoft.com/VisualStudio/feedback/details/802032/std-is-copy-constructible-doesnt-work-correctly , we'd be interested. Otherwise we'll probably have to write one. – Corey Kosak Jan 14 '14 at 15:03