当前位置: 首页 > 知识库问答 >
问题:

对 std::数组的引用大小在编译时不可用

仉洲
2023-03-14

我很想知道为什么下面代码中的第二个static_assert不起作用。似乎即使数组c是对a的引用,数组的大小也嵌入在类型中,因此它应该在编译时可用。

#include <array>

int main()
{
    std::array<int,2> a = {1,2};
    std::array<int,2> b = {2,3};
    std::array<int,2>& c = a;

    static_assert(a.size() == b.size(), "a.size==b.size"); // ok size of array is compile time constant
    static_assert(c.size() == a.size(), "c.size==a.size"); // compiler error "static_assert expression is not an integral constant expression"
}

共有2个答案

穆展鹏
2023-03-14

请注意,如果您将所有声明移出主函数,代码将会编译。为什么?因为< code>a是自动变量,所以它不是真正的编译时对象,并且这里没有省略引用,因此< code>a或< code>c或< code>c.size()都不是< code>constexpr。对于全局变量,< code>a的位置可以在编译时确定。

如果您尝试像这样在函数中绑定它们:

constexpr std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
constexpr const std::array<int,2>& c = a;

你会得到错误,指出 a 不是常量表达式。仍然可以编译的变体:

#include <array>

std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};

int main()
{
    std::array<int,2>& c = a;

    static_assert(a.size() == b.size(), "a.size==b.size"); 
    static_assert(c.size() == a.size(), "c.size==a.size"); 
}
姚晋
2023-03-14

数组的大小嵌入在类型中,因此它应该在编译时可用。

这是真的。但无论如何,c 不是常量表达式,因此将其作为子表达式包含的表达式不能是常量表达式 - 除了某些仅与操作数类型(如 sizeof)交互的运算符

例如,可以使用以下方法获得尺寸:

static_assert(
    std::tuple_size<
        std::remove_reference_t<decltype(c)>
    >::value == a.size(),
    "c.size==a.size"
);

不幸的是,它不是很漂亮。

 类似资料:
  • 我试图用C(11/14)实现fortran的重塑功能,并设计了一个函数。此函数接受两个std::initializer\u列表。第一个initializer\u列表给出了我用来初始化多维数组的初始值。第二个initializer\u列表给出了数组每个维度的大小。我写了一份这样的草稿 这个实现需要给定的非类型模板参数int D,但我想要不带D的东西,比如重塑({1,2,3,4,5,6},{2,3})

  • 问题内容: 当我尝试编译affdex sdk示例应用程序时遇到以下错误 我正在使用GCC 5.2.1 问题答案: 我最初的怀疑是,问题是尝试使用比sdk(gcc v4.8)更高的GCC或GLIBCXX来编译应用程序。 错误msg表示编译器无法找到..的未定义函数。 这里的问题实际上是参数的类型定义(一个std :: string)..编译器正在寻找: 但是,编译库中参数的实际定义类型是.. 事实证

  • 在过去的几个月里,我一直在学习C语言并使用终端。我的代码使用g和c11编译并运行得很好,但在过去几天里它开始出现错误,此后我在编译时遇到了问题。我唯一可以编译和运行的程序依赖于旧的C标准。 我第一次遇到的错误包括 尝试使用ecg$g-o stoi_试验stoi_试验编译。cpp-std=c 11 大堆cpp:13:22:错误:命名空间“std”中没有名为“stoi”的成员;你是说“阿托伊”吗?in

  • 我正在尝试对对象的向量进行排序。我编写了一个函数来比较对象。它似乎在我的编译器上运行得很好,但不是我学校服务器上的编译器。 我收到这个错误。。。 /usr/lib/gcc/i686 redhat linux/4.4.7/../../../..//包括/c/4.4.7/bits/stl\U algo。h: 131:错误:“Student”类型引用的初始化无效 /usr/lib/gcc/i686 re

  • 我想使用部分模板专门化,以便将数组(在编译时创建)“分解”为由其值组成的参数包(以便与我在代码中定义的其他结构接口)。以下内容(我的第一次尝试)不编译 因为模板参数不得涉及模板参数。正如我所理解的,在部分模板专门化中提供非类型参数是不可能的,如果它们不是非常依赖于模板参数的话。因此,我试图通过在类型中包含值来解决这个问题: 我使用并通过,因为我使用非类型模板参数,所以需要c++2a。 在我的实际代

  • 我有一个包含大量选项的JDialog,它工作得很好,但是我已经更改了它,默认情况下,除非用户单击Show Advanced按钮,否则某些选项是不可见的。 当他们这样做时,选项就会显示出来,但是因为对话框不够高,因为它的大小是基于那些选项被隐藏的,所以会添加一个垂直滚动条。 我希望对话框的大小足够大,当高级选项启用。我尝试创建显示高级选项的对话框,根据高级选项可见的情况调用pack()来适应 然后调