Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;堆栈上的可变长度数组_C++_Arrays - Fatal编程技术网

C++ C++;堆栈上的可变长度数组

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编译器中编译此代码?有一些编译器扩展(

我刚刚在项目中遇到了导致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编译器中编译此代码?

有一些编译器扩展(如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]
在任何情况下,都需要更新此代码以使其在VisualStudio上工作

编辑:根据您的评论:


该函数在代码中调用两次,一次调用为
三次_样条(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];
}