函数参数的默认参数是否被视为该参数的初始值设定项?

2024-05-19

假设我有这样的函数声明:

static const int R = 0;
static const int I = 0;

void f(const int& r = R);
void g(int i = I);

根据 [dcl.fct.default]/1:

如果在参数声明中指定了初始化子句 初始化子句用作默认参数 [..]

并且根据语法结构,初始化器可以包括一个初始化子句. Right?

所以我得出的结论是R is an 初始化器对于参数r, and I也是一个初始化器对于参数i.

现在根据 [const.expr]/2:

变量或临时对象o是常量初始化的如果

  • (2.1) 要么它有一个初始化器[..] 和
  • (2.2) 其初始化的完整表达式是一个常量表达式 [..]

因此,两个参数都有一个初始值设定项,并且它们初始化的完整表达式是一个常量表达式。

那么,这两个参数都是r and i经过考虑的常量初始化?


不,因为一个初始化子句不一定是某个的一部分初始化器。这里有问题的语法项目是这个版本的参数声明 https://eel.is/c++draft/dcl.fct#nt:parameter-declaration:

attribute-specifier-seqopt thisopt decl-specifier-seq declarator = initializer-clause

施加适量的头发分裂,这意味着form带有默认参数的参数声明与初始化类似,但仍有细微的不同。最明显的区别是,如果使用实际参数,则默认参数将被忽略。不太明显的是,参数实际上不能被常量初始化,即使它的默认参数是常量表达式。即使该函数仅在编译时求值,这一点仍然成立。下面是一些代码,显示了含义上的细微差别:

#include <random>

// R may be evaluated at compile time and must be constant-initialized
static constexpr int R = 0;

// f may be evaluated at compile time
constexpr int f(const int& r = R) { return r + 42; }

// I must be constant- *or* zero-initialized, even if only evaluated at runtime
constinit const int I = f();

// g is an "immediate function": it may not be evaluated at runtime
consteval int g(int i = I) { return i - 42; }

int main() {
    // A variable that may not appear in constant expressions,
    // because it is not constant-initialized
    const int not_const = std::rand();

    static int x1 = f();                // OK, constant initialization
    // constexpr int x2 = f(not_const); // error, not constant-initialized
    int x3 = f();                       // OK, f() evaluated at compile time
    int x4 = f(not_const);              // OK, evaluated at runtime

    static int y1 = g();                // OK
    // constexpr int y2 = g(not_const); // error
    int y3 = g();                       // OK
    // int y4 = g(not_const);           // error
}

如你看到的here https://godbolt.org/z/qYjo94e6o,这只会生成一个运行时调用f(int const&)没有人g(int)。尽管其他评估的参数实际上是编译时常量,但您既不能使用也不能这样指定它们:

constexpr int f(const int& r = R) {
    // constexpr int x = r; // error, not a constant expression
    return r + 42;
}

consteval int g(int i = I) {
    // constexpr int y = i; // still not a constant expression!
    return i - 42; 
}

// Also not allowed:
// consteval void h(constexpr int x = 0, constinit int y = 1); 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数参数的默认参数是否被视为该参数的初始值设定项? 的相关文章

  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 增强精神、递归和堆栈溢出

    为什么下面的代码在运行时崩溃 它会给出堆栈溢出错误 include
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • C#6 中的长字符串插值行

    我发现 虽然字符串插值在应用于现有代码库的字符串 Format 调用时非常好 但考虑到通常首选的列限制 字符串对于单行来说很快就会变得太长 特别是当被插值的表达式很复杂时 使用格式字符串 您将获得一个可以拆分为多行的变量列表 var str
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐