如何在C++中生成任意嵌套的向量
How to Generate Arbitrarily Nested Vectors in C++?
在C++中,是否可以生成深度(维度)等于用户定义输入的嵌套向量?例如,如果用户输入值为2的整数,则程序可能会创建类型为vector< vector< vector<int> > >
的对象。显然,在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。不管怎样,您的程序是不符合的,因为它超过了执行数量。
如果要处理任意维数的向量,则不能使用递归模板。您必须采用其他技术,这些技术需要在运行时而不是在编译时设置维度。
struct element_t;
struct element_t {
~element_t() {}
using element_p = std::shared_ptr<element_t>;
using data_t = std::variant< std::vector<element_p>, int >;
data_t data;
element_t(element_t const&)=default;
element_t(data_t in):data(std::move(in)) {}
element_t()=default;
};
element_t::data_t generate( unsigned int x ) {
if (x==0) return {unsigned{0}};
auto ptr = std::make_shared<element_t>(generate(x-1));
auto vec = std::vector<element_t::element_p>{ptr};
element_t::data_t r(vec);
return r;
}
测试代码:
void print( element_t::data_t const& in ) {
std::visit(
[](auto const& e)
{
if constexpr( std::is_same< decltype(e), int const& >{} ) {
std::cout << e << "n";
} else {
for (const auto& x:e) {
if (!x)
{
std::cout << "nulln";
}
else
{
std::cout << "nestn";
print(x->data);
std::cout << "unnestn";
}
}
}
},
in
);
}
int main() {
auto r = generate(10);
print(r);
}
实例
- 嵌套在类中时无法设置成员数据
- 无法访问嵌套类.类的使用无效
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 在C++中搜索嵌套多映射值
- 在C++中将矢量转换为嵌套地图
- C++嵌套if语句,基本货币交换
- 在nlohmann json中,如何将嵌套对象的数组转换为嵌套结构的向量
- 嵌套的匿名命名空间
- 了解嵌套循环打印星号图案
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 嵌套for循环C++的问题(初学者)
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 用C#中的并集模拟C++嵌套结构
- 部分专业化和嵌套模板
- 嵌套While循环不起作用(C++问题)
- 在C++中生成任意嵌套的向量
- 如何在C++中生成任意嵌套的向量
- 如何创建任意数量的嵌套循环