C++ 循环中的模板元编程?
几分钟前,我在练习繁琐的算法问题。下面的代码(算法问题的具体逻辑并不重要,因此我们需要知道的是,主函数上面的代码只是TMP): 作者的解释: 从表面上看,if语句可能负责终止递归,就像它与基于“正常”运行时的递归算法一起工作一样。但这就是问题所在。在运行时起作用的东西在编译时不起作用 这是一个无限循环,只会因为编译器将自己限制在某个递归深度而停止。在clang中,我得到一个错误致命错误:递归模板实例化超过了最大深度256。您所选择的编译器可能会出现类似的错误 哎呀…,我只是说说我所知道的 最后,我的问题是: 现在模板的实例化(特别是两次解析)是在编译时进行的。因此,顶级代码中的所有模板实例化都应在编译时进行:C++ 循环中的模板元编程?,c++,c++11,templates,metaprogramming,C++,C++11,Templates,Metaprogramming,几分钟前,我在练习繁琐的算法问题。下面的代码(算法问题的具体逻辑并不重要,因此我们需要知道的是,主函数上面的代码只是TMP): 作者的解释: 从表面上看,if语句可能负责终止递归,就像它与基于“正常”运行时的递归算法一起工作一样。但这就是问题所在。在运行时起作用的东西在编译时不起作用 这是一个无限循环,只会因为编译器将自己限制在某个递归深度而停止。在clang中,我得到一个错误致命错误:递归模板实例化超过了最大深度256。您所选择的编译器可能会出现类似的错误 哎呀…,我只是说说我所知道的 最后,
for (int i = 0; i < 800; i++)
{
for (int j = 0; j < 800; j++)
{
auto temp = oneDArrayMaker<800>::oneDArr[i] + ... // 800 * 800 instantiations should be deternimated at compile time
...
}
...
}
现在,由于scanf
,必须在运行时确定i
和j
。我只是把额外的两个0
传递给stdin
这里是alter main函数之后,输出是12
(正确答案是128)
它已成功编译,并且未生成任何警告。让我困惑的是,输出与原始代码不同(,其输出为128
(等于正确答案)
dubug之后,我发现关键是在修改代码之后,for(;I<800;I++)
只执行一次I=0
,而它应该执行1~799
,这就是12
,而不是128
的原因
问题2:若在运行时无法确定for循环的深度,并且TMP代码存在于循环中,那个么会发生什么?
问题3:如何解释输出12
更新:
问题3已由@Scott Brown解决,我太粗心了
Q1和Q2仍然让我困惑您忘记在(;j<800;j++)的“
之前重置j”
intmain()
{
int n{},ans{},i{},j{};
scanf(“%d”和“&n”);
scanf(“%d%d”、&i和&j);
std::您是否误解了实例化的含义。在这种特殊情况下,它意味着从模板“创建”具体的类/函数。在运行时不会发生这种事情。循环是不相关的。“无限循环”递归实例化模板函数的存在只是因为从函数模板实例化的每个函数都需要另一个实例化,因为作为运行时构造的if
,不影响实例化
#include <iostream>
template<int index> void do_stuff()
{
std::cout << index << std::endl;
}
template<int max_index, int index = 0> void stuff_helper()
{
if (index <= max_index)
{
do_stuff<index>();
stuff_helper<max_index, index + 1>();
}
}
int main()
{
stuff_helper<100>();
return 0;
}
for (int i = 0; i < 800; i++)
{
for (int j = 0; j < 800; j++)
{
auto temp = oneDArrayMaker<800>::oneDArr[i] + ... // 800 * 800 instantiations should be deternimated at compile time
...
}
...
}
int main()
{
int n{}, ans{}, i{}, j{};
scanf("%d", &n);
scanf("%d %d", &i, &j);
std::cout << n << " " << i << " " << j << std::endl;
for (; i < 800; i++)
{
for (; j < 800; j++)
{
auto temp = oneDArrayMaker<800>::oneDArr[i] + oneDArrayMaker<800>::oneDArr[j] + (i+j < 800 ? oneDArrayMaker<800>::oneDArr[i+j] : 100) + 4;
if (temp == n)
{
ans++;
}
}
}
printf("%d", ans);
}
int main()
{
int n{}, ans{}, i{}, j{};
scanf("%d", &n);
scanf("%d %d", &i, &j);
std::cout << n << " " << i << " " << j << std::endl;
int j_orig = j;// here
for (; i < 800; i++)
{
j = j_orig;// and here
for (; j < 800; j++)
{
auto temp = oneDArrayMaker<800>::oneDArr[i] + oneDArrayMaker<800>::oneDArr[j] + (i+j < 800 ? oneDArrayMaker<800>::oneDArr[i+j] : 100) + 4;
if (temp == n)
{
ans++;
}
}
}
printf("%d", ans);
}