繁体   English   中英

类外部的C ++静态constexpr成员重新声明

[英]C++ static constexpr member redeclaration outside of class

对于以下代码,为什么在不重新声明Foo :: bar的情况下main中的第一种情况可以正常工作,而使用该函数的第二种情况则需要它吗?

struct Foo{
static constexpr int bar = 30;
};
//Declaration of Foo::bar outside of struct
constexpr int Foo::bar;
int returnconstexpr(const int& x) { return x; }

int main()
{
    //Ok without declaration outside of struct
    std::cout << Foo::bar << std::endl;

    //Requires declaration outside of struct
    std::cout << returnconstexpr(Foo::bar) << std::endl;

    //Here static constexpr works as a definition
    static constexpr int x = 2;
    std::cout << returnconstexpr(x) << std::endl;

    return 0;
}

我认为这是因为在第一种情况下,编译器实际上只是停留在值中,而在第二种情况下,该函数需要的地址在没有重新声明的情况下尚不存在。 如果是这样,那么我要说的就是声明实际上是一个定义吗? 我对此感到困惑,因为在类中提供了初始化程序,但是它没有使它成为定义。 例如,第三种情况很好。

我认为这是因为在第一种情况下,编译器实际上只是停留在值中,而在第二种情况下,该函数需要的地址在没有重新声明的情况下尚不存在。 如果是这样,那么我要说的就是声明实际上是一个定义吗?

您已经回答了问题。 静态成员是在类外部定义的,因此您拥有的是定义。 当您将其传递给函数时,地址是必需的,因此您需要定义静态成员。 在第一种情况下,编译器只是将Foo::bar替换为该值。

现在将函数签名更改为以下内容:

int returnconstexpr(int x) { return x; }

在上述情况下,您将不再需要定义。

此规则在C ++标准的3.2中:

除非使用x作为满足常量表达式(5.19)出现要求的对象并且ex是表达式e的潜在结果集合的元素,否则将使用其名称显示为可能值表达式ex的变量x。 ,其中将左值到右值转换(4.1)应用于e,或者e是舍弃值表达式(第5条)。

在上述情况下,将立即应用从左值到右值的转换,因此不会被过度使用(如标准所述),并且不需要定义。 简单来说,这意味着它可以只使用值,而无需知道地址,但是,当您使用引用类型(const int&)时,要求编译器知道对象在内存中的位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM