C2977: 'std::tuple' : too many template arguments (MSVC11)

25,501

Solution 1

Check out this entry in the msdn blog. VC++11 doesn't have support for variadic templates. They have something they call faux variadics. Scroll down and you will see a paragraph on Faux variadics that talks about tuples. On that paragraph they say the default maximum number of parameters is 5. You can increase it to 10:

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.

They say they have a fix incoming to make the default 10 again.

Solution 2

In Visual Studio 2012 (VC11) _VARIADIC_MAX is by default defined as 5 in header <xstddef>:

#if !defined(_VARIADIC_MAX)
 #define _VARIADIC_MAX  5

#elif _VARIADIC_MAX < 5 || 10 < _VARIADIC_MAX
 #error _VARIADIC_MAX must be between 5 and 10, inclusive
#endif /* !defined(_VARIADIC_MAX) */

if you have multiple VC11 projects include <tuple> in a solution, it is better to set the macro to all by

1) Shift click to select all C++ projects in your solution

2) Properties, C/C++, Preprocessor, All Configurations All Platforms, Preprocessor Definitions, <Edit>

3) add before <different options> a row

_VARIADIC_MAX=10;

You can change 10 to any number in 6~10.

Solution 3

Setting GTEST_HAS_TR1_TUPLE to 0 in gtest.h helped in my case

Update: of course, the less intrusive way is to define a precompiler flag GTEST_HAS_TR1_TUPLE=0. Check the answers about _VARIADIC_MAX=10 - solves another half of the issue.

Solution 4

In Visual Studio 2013, std::tuple no longer uses _VARIADIC_MAX and now uses actual variardic templates, so this problem should be gone.

If you run into it in 2013, it means you are including the wrong standard library.

Solution 5

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

Share:
25,501
Loom
Author by

Loom

Updated on July 09, 2022

Comments

  • Loom
    Loom almost 2 years

    I'm trying to build googletest with Visual C++ 11, but following code causes an error

    template <typename T1, typename T2, typename T3, typename T4, typename T5,
              typename T6, typename T7, typename T8, typename T9>
    void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, // <-- error C2977
                 ::std::ostream* os) {
      PrintTupleTo(t, os);
    }
    

    That's an error text:

    f:\gtest-1.6.0\include\gtest\gtest-printers.h(550): 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'
    

    And there is the line 72 of utility-file:

    template<class = _Nil, _MAX_CLASS_LIST>
       class tuple; // Line 72
    

    What is the problem with std::tuple and how to fix it?

    (BTW: I'm tried unsuccessfully to change std::tr1::tuple to std::tuple )

  • rubenvb
    rubenvb over 12 years
    They should just implement variadic templates instead of fixing things broken by design.
  • Ark-kun
    Ark-kun over 11 years
    @rubenvb How can you implement something when it's having breaking changes and people are yelling that you don't support some feature just because you were suppport the "old" variation? The C++ draft set the minimum number of parameters which was 10. In fact, here is what the GCC authors wrote "In the GCC standard library implementation, excessive compilation times forced reverting the maximum number of supported parameters from the original twenty to ten—the smallest value allowed by the draft standard [10]. " (jot.fm/issues/issue_2008_02/article2)
  • rubenvb
    rubenvb over 11 years
    @Ark-kun Have you even read the answer or the blog post it links to? MSVC 2012 does not have variadic templates (unless you want to try your hands on the experimental November CTP, in which case the library headers will probably still be broken without real variadic template support). My comment was not about the number of template arguments, but the implementation itself. And an article from 2008 is not something I'm interested in in 2013.
  • Ark-kun
    Ark-kun over 11 years
    @ruvenvb The product development has a certain momentum. Visual Studio 2012 had a correct implementation of the standard draft when its development was started. Then, the C++ draft changed. The C++11 standard was released in August 2011 (a month before the MSDN blog post) when it was a bit too late in the product cycle to reimplement and retest a very complex feature such as variadic templates. My point is "Don't blame the product for a "non-standard" feature implementation, when the standard has just changed (or is not yet released)."
  • Roee Gavirel
    Roee Gavirel about 11 years
    I liked this answer, doesn't effect the rest of the code (: (P.s. microsoft sucks)
  • Jichao
    Jichao over 10 years
    blogs.msdn.com/b/vcblog/archive/2013/06/28/… we lowered infinity from 10 to 5 in Visual C++ 2012 in order to improve compile times for most users (we provided a way to request the old limit of 10 through a macro, _VARIADIC_MAX). In Visual C++ 2013, we have thoroughly eradicated the faux variadic macros. If you want tuples with 50 types, you can have them now. Furthermore, I am pleased to announce that switching the STL over to real variadic templates has improved compile times and reduced compiler memory consumption.
  • 101010
    101010 about 10 years
    This is the best and most clean answer by far, You're the one that should have earned that tick. Thanks a lot mate.
  • Gonen I
    Gonen I almost 10 years
    and don't forget to add a semi-colon _VARIADIC_MAX=10;