C++ C++;堆栈上的可变长度数组
我刚刚在项目中遇到了导致Visual Studio 2012编译器失败的代码。它的形式如下:C++ C++;堆栈上的可变长度数组,c++,arrays,C++,Arrays,我刚刚在项目中遇到了导致Visual Studio 2012编译器失败的代码。它的形式如下: void CLASS cubic_spline (const int *x_, const int *y_, const int len) { float A[2*len][2*len], b[2*len], c[2*len], d[2*len]; ... 问题是在堆栈上创建这些可变长度数组。我从未真正见过这样的代码——是否可以在Visual Studio编译器中编译此代码?有一些编译器扩展(
void CLASS cubic_spline (const int *x_, const int *y_, const int len)
{
float A[2*len][2*len], b[2*len], c[2*len], d[2*len];
...
问题是在堆栈上创建这些可变长度数组。我从未真正见过这样的代码——是否可以在Visual Studio编译器中编译此代码?有一些编译器扩展(如and)允许这样做,但它还不是标准的 在C++11中,如果数值为常量,也可以使用。并最终提交规范 如果
x_
和y_
是数组,则可以按如下方式使用:
template<std::size_t size>
void CLASS cubic_spline (std::array<int, size> const& x, std::array<int, size> const& y)
{
using float_array = std::array<float, 2 * size>;
std::array<float_array, 2 * size> A;
float_array b, c, d;
// ...
}
这是特定于GCC的编译器扩展,请参阅。我不知道有什么编译器选项可以让它们在VC中开箱即用。如果这是一个非常孤立的问题,请尝试预处理器
#ifdef
s为VC提供不同的代码。如前所述,VLA(可变长度数组)是C功能,更重要的是,它是Visual Studio不支持的C99功能。在Linux上,Clang和GCC都支持C99(和C11我相信),并允许C++中的语法作为扩展。
在C++中,您可以通过切换到所有简单数组的代码> STD::vector < /代码>,轻松地转换代码。只有A
需要更多的工作:
- 您可以使用
,但这样会失去连续性和局部性std::vector
- 或者您可以使用展平版本
但随后您将无法访问std::vector a(2*len*2*len)
,而必须将其转换为A[i][j]
A[i*2*len+j]
该函数在代码中调用两次,一次调用为
三次_样条(cx,cf,9)
和一次作为三次_样条(cx,cf,18)代码>。在第一个示例中,cx
和cy
是int[9]
,在第二个示例中是int[18]
在这种情况下,您实际上可以将函数设置为模板:
template <size_t len>
void CLASS cubic_spline(int const (&x)[len], int const (&y)[len]) {
float A[2*len][2*len], b[2*len], c[2*len], d[2*len];
}
模板
void类三次样条曲线(整数常量(&x)[len],整数常量(&y)[len]){
浮动A[2*len][2*len],b[2*len],c[2*len],d[2*len];
}
请注意,我删除了最后一个参数,因为它不再是必需的。<代码> x和 y>代码>是代码> int const(&)[Le] ,它是对长度为<代码> Le<代码> > > < /p> DcDRAW的数组,而不是C++。C和C++是两种不同的语言,语法相似。除了编译器扩展(La GCC)之外,C++不支持。我没有意识到可变长度数组是有效的C而不是C++。我的错误是错误地将问题标记为C++:区分不同的语言通常不那么重要,但在这种情况下,它似乎很重要@阿德瓦克:我必须猜出那个错误是什么吗?这是一种困惑吗?这个信息总是相关的,我不明白你为什么要千方百计向当局隐瞒。你是有问题的人,所以你没有资格决定某些细节没有帮助。如果利用constexpr语法,这段代码会是什么样子?@aardvarkk:constexpr
只适用于编译时计算,对你合适吗?@aardvarkk,很难说,因为constepr
不能盲目地用来代替const
。例如,不能将constexpr
作为函数参数。在您的示例中,x
和y
是什么?该函数在代码中被调用两次,一次被称为cubic_样条(cx,cf,9)
和一次作为三次_样条(cx,cf,18)代码>。在第一个示例中,cx
和cy
是int[9]
,而在第二个示例中,它们是int[18]
。这是一个关于C的问题,变长数组是C99的标准核心功能。不需要扩展。非常有用的帖子,谢谢。我知道VS不支持C99,所以它直接回答了这个问题,知道VLAs不仅是C的特性,而且是C99的一个特性。AADVARKK:实际上,如果在编译时知道了这些维度,那么只需转换代码“C++”的签名就可以更容易地处理这个问题,从而使它成为标准C++。我编辑我的答案是为了展示函数模板中数组引用的威力:)不正确。VLA是C99标准的特性(这个问题用C++标记为C)。无论如何,DCWRAW是一个C程序。我想它最终应该被重新标记为C:)这是我的错误——我错误地把它标记为C++而不实现代码> dcWrase/Cuffel>实际上是用C编写的。这似乎是C和C++之间真正不同的几个东西之一。
template <size_t len>
void CLASS cubic_spline(int const (&x)[len], int const (&y)[len]) {
float A[2*len][2*len], b[2*len], c[2*len], d[2*len];
}