Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++ 如何初始化constexpr引用_C++_C++11_Reference_Constexpr - Fatal编程技术网

C++ 如何初始化constexpr引用

C++ 如何初始化constexpr引用,c++,c++11,reference,constexpr,C++,C++11,Reference,Constexpr,我试图初始化constexpr引用,但没有成功。我试过了 #include <iostream> constexpr int& f(int& x) // can define functions returning constexpr references { return x; } int main() { constexpr int x{20}; constexpr const int& z = x; // error here

我试图初始化
constexpr
引用,但没有成功。我试过了

#include <iostream>

constexpr int& f(int& x) // can define functions returning constexpr references
{
    return x;
}

int main()
{
    constexpr int x{20};
    constexpr const int& z = x; // error here
}
#包括
constexpr int&f(int&x)//可以定义返回constexpr引用的函数
{
返回x;
}
int main()
{
constexpr int x{20};
constexpr const int&z=x;//此处出错
}
但是我得到了一个编译时错误

错误:constexpr变量“z”必须由常量表达式初始化

删除
常量将导致

错误:将对类型“int”的引用绑定到类型“const int”的值会删除限定符

尽管我觉得
constexpr
自动暗示变量声明的
const

因此,我的问题是:

  • constexpr
    引用有用吗?(即,比
    const
    references“更好”)
  • 如果是,我如何有效地定义它们
  • 附言:我已经看到了一些与我相关的问题,例如,但我认为它们没有解决我的问题

  • constexpr引用有用吗?(即“优于”常量引用)
  • 它们保证在程序启动之前初始化,而对const的引用可以在程序开始运行后的动态初始化期间初始化

  • 如果是,我如何有效地定义它们
  • constexpr
    引用必须绑定到全局变量,而不是局部变量(或者更正式地说,它必须绑定到具有静态存储持续时间的对象)


    引用在概念上等同于获取变量的地址,局部变量的地址不是常量(即使在
    main
    中,也只能调用一次,因此其局部变量只初始化一次)因此,问题是constepr引用需要绑定到具有静态存储持续时间的对象,这在
    5.19节[expr.const](强调部分)中有介绍:

    引用常量表达式是左值 指定具有静态存储持续时间的对象或函数的核心常量表达式

    修改措辞:

    常量表达式是glvalue核心常量表达式,其值引用具有静态属性的对象 存储持续时间或函数,或其值为对象的prvalue核心常量表达式,其中 该对象及其子对象:

    • 引用类型的每个非静态数据成员都引用具有静态存储持续时间的对象或 功能,以及
    • 如果对象或子对象是指针类型,则它包含具有静态存储的对象的地址 持续时间,超过该对象结尾的地址(5.7)、函数地址或空指针 价值观
    因此,像这样更改
    x
    的声明将有效:

    constexpr static int x{20};
    
    如前所述,初始值设定项需要是具有静态存储持续时间的对象

    N4140/§5.19/4常量表达式是glvalue核心或 其值引用具有静态属性的对象的常量表达式 存储持续时间[…]

    N4140/§7.1.5/9对象声明中使用的
    constexpr
    说明符 将对象声明为常量。此类对象应具有文字类型 并应初始化。[…]否则,或者如果a
    constexpr
    说明符用于引用声明中,每个完整表达式 出现在初始值设定项中的应为常量表达式


    在N3337中,措辞是不同的。

    它们需要绑定到具有静态存储持续时间的内容,可以是本地的
    静态的
    或全局的。
    constexpr
    影响引用,而不是它绑定到的类型,因此要绑定到
    const int
    您仍然需要
    const int&
    @antred[basic.start.main]/3:“程序中不得使用功能
    main
    main
    的链接由实现定义。将
    main
    定义为已删除或声明main为
    inline
    static
    constexpr
    的程序格式错误。名称
    main
    没有其他保留。“@antred我不是C专家,但快速查看N1570没有显示类似的限制。5.1.2.2.3/1程序终止会说“如果
    main
    函数的返回类型与
    int
    兼容,从初始调用到
    main
    函数的返回相当于调用
    exit
    函数,将
    main
    函数返回的值作为其参数…[强调添加]。这似乎意味着对main的非初始调用是兼容的。@T.C.”它可以是本地
    static
    或全局的“或其生存期延长到静态存储持续时间的临时存储:
    static constexpr int const&x=42很好。这也是为什么
    static constexpr auto x={1,2},但
    constexpr auto x={1,2}不是(在块范围内)。(这意味着OP代码中的static constexpr const int&z=+x;
    都是合法的。)