2

MSVC++ 还不支持可变参数模板,因此它的标准库std::tuple通过使用宏来为类“伪造”这些模板。我最近尝试用 VC11 beta 编译我的一个项目,并得到了展示:

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

我听说有一个#define可以设置在某个地方来改变这个设置,但我(为了我的一生)不记得它是什么。它是什么?

4

3 回答 3

6

您可以定义_VARIADIC_MAX为 5 到 10 之间的任何值,包括 5 到 10。

可以在 MSDN 文章“ C++11 特性(现代 C++) ”中找到这一点以及有关 Visual C++ 11 的许多其他有趣事实。这个特殊的宏在“Faux variadics”一节中讨论。

于 2012-03-06T17:59:41.453 回答
2

来自blogs.msdn.com文章的有趣引用:

虚假可变参数:我们开发了一种模拟可变参数模板的新方案。以前在 VC9 SP1 和 VC10 中,我们反复包含子标题,每次都定义不同的宏,以消除 0、1、2、3 等参数的重载。(例如,重复包含内部子标题,以消除 make_shared(args, args, args)。)在 VC11 中,子标题消失了。现在我们将可变参数模板本身定义为宏(有很多反斜杠延续),然后用主宏扩展它们。此内部实现更改具有一些用户可见的效果。首先,代码更易于维护,更易于使用(添加子标题是一项相当大的工作量),并且不那么难以理解。这使我们能够轻松实现可变参数放置,并且应该使将来更容易消除错误。其次,使用调试器更难介入(对不起!)。第三,pair 的 pair(piecewise_construct_t, tuple, tuple) 构造函数具有“有趣”的效果。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。其次,使用调试器更难介入(对不起!)。第三,pair 的 pair(piecewise_construct_t, tuple, tuple) 构造函数具有“有趣”的效果。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。其次,使用调试器更难介入(对不起!)。第三,pair 的 pair(piecewise_construct_t, tuple, tuple) 构造函数具有“有趣”的效果。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。pair 的 pair(piecewise_construct_t, tuple, tuple) 构造函数具有“有趣”的效果。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。pair 的 pair(piecewise_construct_t, tuple, tuple) 构造函数具有“有趣”的效果。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。这需要 N^2 个重载(如果我们支持最多 10 个元组,这意味着 121 个重载,因为这里也计算空元组)。我们最初观察到这(垃圾邮件发送出如此多的对元组重载,加上所有的 emplacement 重载)在编译期间消耗了大量内存,因此作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。所以作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。所以作为一种解决方法,我们减少了无穷大。在 VC9 SP1 和 VC10 中,infinity 为 10(即“可变参数”模板支持 0 到 10 个参数(包括)。在 VC11 Developer Preview 中,infinity 默认为 5。这使我们的编译器内存消耗恢复到 VC10 中的水平。 如果您需要更多参数(例如,您有使用 6 元组的 VC9 SP1 或 VC10 编译的代码),则有一个逃生舱口。您可以在 5 到 10 之间定义 _VARIADIC_MAX 项目范围(默认为 5)。 增加它会使编译器消耗更多内存,并且可能需要您使用 /Zm 选项为 PCHe 保留更多空间。

于 2012-03-06T18:03:46.870 回答
1

这在修订版 675 中已修复。请参阅https://code.google.com/p/googletest/source/detail?r=675

于 2014-01-13T23:06:35.480 回答