【问题标题】:关于 func(const int&) 和 func(const int)
【发布时间】:2022-01-23 13:08:27
【问题描述】:
#include <iostream>

class Account {
public:
    static double GetCircumference(const double &dR) { return 2 * dR * 3.1415926; }
    static constexpr double cd = 3.0;
};

// constexpr double Account::cd;

int main()
{
    std::cout << Account::GetCircumference(Account::cd) << std::endl;
}

除非我删除“//”,否则代码是错误的。 但是,如果我只将 (const double &dR) 更改为 (const double dR),它也可以。 为什么?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    在 C++11 中,这个类内声明:

    static constexpr double cd = 3.0;
    

    不是一个定义(...直到 C++17;之后constexpr 静态数据成员被隐式内联)。

    这是一个类外的定义:

    constexpr double Account::cd;
    

    如果Account::cdodr-used,则需要定义,如果将其传递给:

    double GetCircumference(const double &dR);
    

    作为参考。

    [basic.def.odr]/3 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义;无需诊断。 [...]

    但是,如果传递给

    double GetCircumference(const double dR);
    

    它不是 odr-used:

    [basic.def.odr]/2 表达式可能会被计算,除非它是未计算的操作数(子句 [expr])或其子表达式。名称显示为潜在求值表达式的变量是 odr-used 除非它是满足出现在常量表达式中的要求的对象 ([expr.const]) 和左值右值转换 ([conv.lval]) 立即应用

    并且不需要定义。

    【讨论】:

    • 谢谢!这很有帮助。而且我还想知道当我将 constexpr int 传递给 func(const int &) 时会发生什么?当 constexpr 被“替换”时,内存中是否还有一个地址? @dfrib
    • @Mikato 上面的答案也适用于我们用int 替换double 的情况:当一个变量不被odr 使用时的规则与a) 它是否可能出现在一个常量表达式,以及 b) [conv.lval]/2 是否应用使得不引用原始对象(而是产生一个右值)。定义的要求来自[basic.def.odr]/3;即应定义任何用于 odr 的变量。我已经相应地扩展了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 2010-09-16
    相关资源
    最近更新 更多