在C中,是否可以生成一个深度(维度)等于用户定义输入的嵌套向量?例如,如果用户输入值为2的整数,则一个程序可能会创建一个类型为vector<的对象.矢量<矢量<诠释> >取代.显然,有许多其他方法可以轻松地在C中实现类似的行为,但我纯粹感兴趣的是,是否可以实际生成任意嵌套的向量.最初,我认为这将是相当微不足道的,但我的实现都以相当奇怪的方式失败了.
#include<iostream> #include<vector> using namespace std; template<typename A> void vec_print(vector<A> in){ cout << "{"; for(typename vector<A> :: iterator i = in.begin(); i != in.end(); ++i){ cout << *i << ","; } cout << "}" << endl; } template<typename B> void vec_print(vector< vector<B> > in){ cout << "{"; for(typename vector< vector<B> > :: iterator i = in.begin(); i != in.end(); ++i){ vec_print(*i); cout << ","; } cout << "}" << endl; } template<typename T> auto generate(unsigned int d){ if(d == 0){ vector<T> in; return in; } return generate< vector<T> >(d - 1); } int main(){ unsigned int d = 0; cin >> d; vec_print(generate<int>(d)); return 0; }
最初,我认为这可能有用,但由于我对C编译器如何处理模板函数的理解,我对此非常怀疑.使用带有–std = c 11标志的g编译器,在崩溃之前,g编译器递归地发出错误,通知我函数返回类型推导仅在C 17规范下可用.尝试使用–std = c 17标志编译此程序导致没有错误,但编译器只是崩溃.我怀疑编译器试图生成无限数量的,或者可能是2 ^ 31个模板函数,尽管我希望它能够通过生成无限模板函数的错误警告来处理它,而不是静默死亡.
解决方法
该标准设置了符合程序不应超过的嵌套模板实例化深度(1024)的限制.但是,实现不需要强制执行或诊断此限制或任何其他实现限制.它可能无法编译任何“太大”的程序.
gcc和clang都可以使用标志来设置用户定义的模板实例化深度限制.为了了解发生了什么,请使用
g++ -std-c++17 -ftemplate-depth-20 yourprogram.cpp >& gcc.log
并查看生成的日志文件有多大.然后将深度增加到21并再次执行.做多次,然后将你的发现推断到-ftemplate-depth-1024.
当然编译器崩溃是一个QoI问题,应该被认为是一个bug.无论如何,您的程序不符合要求,因为它超出了实施数量.
如果要处理任意数量维度的向量,则不能使用递归模板.您必须使用其他技术,这些技术需要在运行时而不是在编译时设置维度.