C ++ 1y / C ++ 14:不允许在常量表达式中分配对象的生存期吗?

安德鲁·托马佐斯(Andrew Tomazos)

以下C ++ 14 / C ++ 1y程序是否根据当前草案格式错误?

#include <cstddef>

template<typename T, size_t n>
struct literal_array
{
    T data[n];
};

template<typename T, size_t n, size_t m>
constexpr literal_array<T, n+m> operator+(literal_array<T, n> a,
                                          literal_array<T, m> b)
{
    literal_array<T, n+m> x;

    for (size_t i = 0; i < n; i++)
        x.data[i] = a.data[i];

    for (size_t i = 0; i < m; i++)
        x.data[n+i] = b.data[i];

    return x;
}

int main()
{
    constexpr literal_array<int, 3> a = { 1, 2, 3 };
    constexpr literal_array<int, 2> b = { 4, 5 };

    constexpr auto c = a + b;
}

lang主干(在撰写本文时)给出:

error: constexpr variable 'c' must be initialized by a constant expression
        constexpr auto c = a + b;
                       ^   ~~~~~
assignment to object outside its lifetime is not allowed in a constant expression
                x.data[i] = a.data[i];
                          ^
in call to 'operator+({{1, 2, 3}}, {{4, 5}})'
        constexpr auto c = a + b;
                           ^

什么是“在其生命周期之外分配对象”?x及其子对象的生命周期封装了该函数,那么它的作用是什么?

沙菲克·雅格莫(Shafik Yaghmour)

如果将定义更改为以下内容,则该程序格式不正确x因为您尚未初始化

literal_array<T, n+m> x = {{0}};

clang不再抱怨,它编译没有错误。另一个解决方案是创建constexpr构造器

我们可以在标准草案7.1.5 的constexpr说明符3段中找到该内容,该内容为:

constexpr函数的定义应满足以下约束:

并包括以下项目符号:

功能主体应为= delete= default不包含复合语句

其中包含以下项目符号(重点是我的):

非文字类型或静态或线程存储持续时间的变量的定义,或者不对其执行初始化的变量

稍后我们有以下示例:

constexpr int uninit() {
  int a; // error: variable is uninitialized
  return a;
}

标准草案x似乎不存在关于的使用寿命的投诉据我所知,正确的原因应该是与...相似的东西object is not initialized

有关对象生存期的标准草案中的相关引用应为“对象生存3.8 期”1,其中指出:

对象生存期是对象的运行时属性。如果对象属于类或聚合类型,并且其或其成员之一由除普通缺省构造函数之外的构造函数初始化,则称该对象具有非普通初始化。[注意:通过琐碎的复制/移动构造函数进行的初始化是非琐碎的初始化。结束说明]类型的对象的生存期在以下情况下T开始:

  • 获得具有适合类型的对齐方式和大小的存储T,并且
  • 如果对象具有非平凡的初始化,则其初始化完成。

万一我丢失了一些东西,我也使用std :: is_trivial进行了检查

std::cout <<  std::boolalpha << std::is_trivial<literal_array<int, 3>>::value << std::endl ;

结果如预期true

更新

为此提交了一个错误报告,答复中包含以下声明:

[...]问题是我们还没有实现不能在常量表达式中调用该函数的隐含规则。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++ 1y / C ++ 14:不允许在常量表达式中分配对象的生存期吗?

来自分类Dev

C ++ 1y / 14:自动变量模板?

来自分类Dev

gcc编译选项std = c ++ 1y和std = c ++ 14之间的区别

来自分类Dev

C结构对象堆栈-常量表达式中不允许函数调用(错误)

来自分类Dev

C ++ 1y中的内存管理中的大小调整分配功能

来自分类Dev

C ++:元组列表C ++ 11 / 1y

来自分类Dev

返回类型推导的类方法?C ++ 1y

来自分类Dev

CRTP和c ++ 1y返回类型推导

来自分类Dev

C ++ 1y自动功能类型推导

来自分类Dev

C ++ 1y的内存管理中的定型释放功能

来自分类Dev

在qt(mingw)中启用c ++ 1y

来自分类Dev

C ++ 1y / C ++ 14:将静态constexpr数组转换为非类型模板参数包?

来自分类Dev

c ++ 1y将允许派生类对基类变量进行类内初始化吗?

来自分类Dev

C ++ 14 / 1y:“ operator +必须带有一个或两个参数”的标准引用?

来自分类Dev

C中的“声明不允许在此处”和“常量表达式”错误

来自分类Dev

在C ++ 11或C ++ 1y中对非类型模板参数包进行排序?

来自分类Dev

此递归多态C ++ 1y lambda调用有什么问题?

来自分类Dev

在C ++ 1y中是否需要公共的类typedef?

来自分类Dev

c ++ 11 / 1y lambda函数的类型签名是什么?

来自分类Dev

C ++ 1y没有从std :: bind到std :: function的可行转换

来自分类Dev

比较C ++ 20常数表达式中允许的动态分配对象的地址吗?

来自分类Dev

const_cast在常量表达式中有效吗?(C ++ 14,C ++ 17)

来自分类Dev

c ++:“期望的常量表达式”

来自分类Dev

在C ++ 1y中,'constexpr'非静态成员函数不会隐式地成为'const';添加“ const”以避免行为改变

来自分类Dev

了解有关C ++ 1y的提案N3650中有关可恢复功能的示例

来自分类Dev

正则表达式匹配 1Y 但不匹配 Javascript 中的 1YY

来自分类Dev

-O1 / 2/3,带有-std = c ++ 1y / 11/98-如果包含<cmath>,我会收到错误消息:在此范围内未声明'_hypot'

来自分类Dev

C ++ 11之前的“常量表达式”

来自分类Dev

静态断言C ++-常量表达式错误

Related 相关文章

  1. 1

    C ++ 1y / C ++ 14:不允许在常量表达式中分配对象的生存期吗?

  2. 2

    C ++ 1y / 14:自动变量模板?

  3. 3

    gcc编译选项std = c ++ 1y和std = c ++ 14之间的区别

  4. 4

    C结构对象堆栈-常量表达式中不允许函数调用(错误)

  5. 5

    C ++ 1y中的内存管理中的大小调整分配功能

  6. 6

    C ++:元组列表C ++ 11 / 1y

  7. 7

    返回类型推导的类方法?C ++ 1y

  8. 8

    CRTP和c ++ 1y返回类型推导

  9. 9

    C ++ 1y自动功能类型推导

  10. 10

    C ++ 1y的内存管理中的定型释放功能

  11. 11

    在qt(mingw)中启用c ++ 1y

  12. 12

    C ++ 1y / C ++ 14:将静态constexpr数组转换为非类型模板参数包?

  13. 13

    c ++ 1y将允许派生类对基类变量进行类内初始化吗?

  14. 14

    C ++ 14 / 1y:“ operator +必须带有一个或两个参数”的标准引用?

  15. 15

    C中的“声明不允许在此处”和“常量表达式”错误

  16. 16

    在C ++ 11或C ++ 1y中对非类型模板参数包进行排序?

  17. 17

    此递归多态C ++ 1y lambda调用有什么问题?

  18. 18

    在C ++ 1y中是否需要公共的类typedef?

  19. 19

    c ++ 11 / 1y lambda函数的类型签名是什么?

  20. 20

    C ++ 1y没有从std :: bind到std :: function的可行转换

  21. 21

    比较C ++ 20常数表达式中允许的动态分配对象的地址吗?

  22. 22

    const_cast在常量表达式中有效吗?(C ++ 14,C ++ 17)

  23. 23

    c ++:“期望的常量表达式”

  24. 24

    在C ++ 1y中,'constexpr'非静态成员函数不会隐式地成为'const';添加“ const”以避免行为改变

  25. 25

    了解有关C ++ 1y的提案N3650中有关可恢复功能的示例

  26. 26

    正则表达式匹配 1Y 但不匹配 Javascript 中的 1YY

  27. 27

    -O1 / 2/3,带有-std = c ++ 1y / 11/98-如果包含<cmath>,我会收到错误消息:在此范围内未声明'_hypot'

  28. 28

    C ++ 11之前的“常量表达式”

  29. 29

    静态断言C ++-常量表达式错误

热门标签

归档