<i id='4l806'><tr id='4l806'><dt id='4l806'><q id='4l806'><span id='4l806'><b id='4l806'><form id='4l806'><ins id='4l806'></ins><ul id='4l806'></ul><sub id='4l806'></sub></form><legend id='4l806'></legend><bdo id='4l806'><pre id='4l806'><center id='4l806'></center></pre></bdo></b><th id='4l806'></th></span></q></dt></tr></i><div id='4l806'><tfoot id='4l806'></tfoot><dl id='4l806'><fieldset id='4l806'></fieldset></dl></div>
      <tfoot id='4l806'></tfoot>

        • <bdo id='4l806'></bdo><ul id='4l806'></ul>
        <legend id='4l806'><style id='4l806'><dir id='4l806'><q id='4l806'></q></dir></style></legend>

        <small id='4l806'></small><noframes id='4l806'>

        投入 constexpr 函数

        时间:2023-09-18

      1. <i id='M8zrU'><tr id='M8zrU'><dt id='M8zrU'><q id='M8zrU'><span id='M8zrU'><b id='M8zrU'><form id='M8zrU'><ins id='M8zrU'></ins><ul id='M8zrU'></ul><sub id='M8zrU'></sub></form><legend id='M8zrU'></legend><bdo id='M8zrU'><pre id='M8zrU'><center id='M8zrU'></center></pre></bdo></b><th id='M8zrU'></th></span></q></dt></tr></i><div id='M8zrU'><tfoot id='M8zrU'></tfoot><dl id='M8zrU'><fieldset id='M8zrU'></fieldset></dl></div>
          <tbody id='M8zrU'></tbody>
        <legend id='M8zrU'><style id='M8zrU'><dir id='M8zrU'><q id='M8zrU'></q></dir></style></legend>
            • <bdo id='M8zrU'></bdo><ul id='M8zrU'></ul>
              <tfoot id='M8zrU'></tfoot>

                  <small id='M8zrU'></small><noframes id='M8zrU'>

                1. 本文介绍了投入 constexpr 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  以下代码在 clang++ 3.7.0 下编译,但被 g++ 5.3.1 拒绝.两者都有 -std=c++14 选项.哪个编译器是正确的?任何人都知道标准中的哪里谈论这个?谢谢.

                  The following piece of code compiles under clang++ 3.7.0 but is denied by g++ 5.3.1. Both have -std=c++14 option. Which compiler is correct? Anyone knows where in the standard talks about this? Thanks.

                  #include <stdexcept>
                  using namespace std;
                  
                  constexpr int f(int n) {
                    if (n <= 0) throw runtime_error("");
                    return 1;
                  }
                  
                  int main() {
                    char k[f(1)];
                  }
                  

                  输出

                  [hidden] g++ -std=c++14 c.cpp 
                  c.cpp: In function ‘constexpr int f(int)’:
                  c.cpp:7:1: error: expression ‘<throw-expression>’ is not a constant-expression
                   }
                   ^
                  [hidden] clang++ -std=c++14 c.cpp 
                  [hidden] 
                  [hidden] g++ -v
                  Using built-in specs.
                  COLLECT_GCC=/usr/bin/g++
                  COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper
                  Target: x86_64-redhat-linux
                  Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
                  Thread model: posix
                  gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC) 
                  [hidden] 
                  [hidden] clang++ -v
                  clang version 3.7.0 (http://llvm.org/git/clang.git 2ddd3734f32e39e793550b282d44fd71736f8d21)
                  Target: x86_64-unknown-linux-gnu
                  Thread model: posix
                  Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/3.4.6
                  Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.3.1
                  Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/5.3.1
                  Candidate multilib: .;@m64
                  Candidate multilib: 32;@m32
                  Selected multilib: .;@m64
                  

                  推荐答案

                  clang 是正确的,注意 HEAD 修订版gcc 接受 也接受此代码.这是一个格式良好的 constexpr 函数,只要参数的值允许该函数被评估为核心常量表达式.在您的情况下 1 就是这样一个值.

                  clang is correct, note the HEAD revision of gcc accepts also accepts this code. This is a well-formed constexpr function, as long as there is value for the argument(s) that allows the function to be evaluated as a core constant expression. In your case 1 is such a value.

                  这在 C++14 标准草案部分 7.1.5 中包含了 constexpr 说明符 [dcl.constexpr],它告诉我们在 constexpr 函数中允许什么:

                  This is covered in the draft C++14 standard section 7.1.5 The constexpr specifier [dcl.constexpr] which tells us what is allowed in a constexpr function:

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

                  The definition of a constexpr function shall satisfy the following constraints:

                  • 它不应是虚拟的 (10.3);

                  • it shall not be virtual (10.3);

                  它的返回类型应该是一个文字类型;

                  its return type shall be a literal type;

                  它的每个参数类型都应该是一个文字类型;

                  each of its parameter types shall be a literal type;

                  它的函数体应该是=delete,=default,或者一个不包含的复合语句

                  its function-body shall be = delete, = default, or a compound-statement that does not contain

                  • 一个汇编定义,

                  • an asm-definition,

                  goto 语句,

                  尝试块,或

                  非文字类型或静态或线程存储持续时间的变量的定义或不进行初始化.

                  a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

                  throw 没有限制,它还说(强调我的):

                  no restriction on throw and it also says (emphasis mine):

                  对于非模板、非默认的 constexpr 函数或非模板、非默认、非继承的函数constexpr 构造函数,如果不存在参数值使得函数或构造函数的调用可能是核心常量表达式 (5.19) 的计算子表达式,程序格式错误;不需要诊断.

                  For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.

                  在本段下方,我们有以下示例,与您的示例类似:

                  and below this paragraph we have the following example, similar to yours:

                  constexpr int f(bool b)
                    { return b ? throw 0 : 0; } // OK
                  constexpr int f() { return f(true); } // ill-formed, no diagnostic required
                  

                  throw 在核心常量表达式中不允许,这在 5.19 部分有介绍 [expr.const] 段落 2 表示:

                  throw is not allowed in a core constant expression, which is covered in section 5.19 [expr.const] paragraph 2 which says:

                  条件表达式 e 是核心常量表达式,除非对 e 求值,遵循规则抽象机 (1.9),将评估以下表达式之一

                  A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions

                  并包括以下项目符号:

                  • 抛出表达式 (15.1).

                  所以当 n <= 0 时,f 将不能用于核心常量表达式.

                  and so f would not be usable in a core constant expression when n <= 0.

                  更新

                  正如 TemplateRex 指出的那样,有两个 gcc 错误报告:

                  As TemplateRex points out, there are two gcc bugs reports for this:

                  • 在 constexpr 函数中从未执行过的throw"未能编译
                  • C++14] throw-expression 不是有效的常量表达式

                  TemplateRex 还指出这些修复不适用于 5.3.0 并且仅在主干中.不,提供了解决方法.

                  TemplateRex also notes the fixes are not applied to to 5.3.0 and are only in trunk. No, work arounds are provided.

                  这篇关于投入 constexpr 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:对成员“..."的请求在 g++ 中不明确 下一篇:什么是“条"?(GCC 应用程序)用于?

                  相关文章

                  最新文章

                    <bdo id='jYlqD'></bdo><ul id='jYlqD'></ul>
                  <legend id='jYlqD'><style id='jYlqD'><dir id='jYlqD'><q id='jYlqD'></q></dir></style></legend>

                  <i id='jYlqD'><tr id='jYlqD'><dt id='jYlqD'><q id='jYlqD'><span id='jYlqD'><b id='jYlqD'><form id='jYlqD'><ins id='jYlqD'></ins><ul id='jYlqD'></ul><sub id='jYlqD'></sub></form><legend id='jYlqD'></legend><bdo id='jYlqD'><pre id='jYlqD'><center id='jYlqD'></center></pre></bdo></b><th id='jYlqD'></th></span></q></dt></tr></i><div id='jYlqD'><tfoot id='jYlqD'></tfoot><dl id='jYlqD'><fieldset id='jYlqD'></fieldset></dl></div>
                  1. <tfoot id='jYlqD'></tfoot>
                  2. <small id='jYlqD'></small><noframes id='jYlqD'>