引用静态数据成员
referencing static data member
我正在阅读有关绑定对静态数据成员的引用或获取其地址的内容,如果(且仅当(它具有类外定义(https://isocpp.org/wiki/faq/classes-and-objects#in-class-constant(。
当我尝试测试该示例(见下文(时,我注意到它可以在Visual Studio 2017上运行(没有预期的错误(。
我尝试使用在线编译器,但只收到一个错误(不是预期的两个(。
#include <iostream>
using namespace std;
class AE {
public:
static const int c6 = 7;
static const int c7 = 31;
};
const int AE::c7; // definition
void byref(const int& a);
int main(int argc, char* argv[])
{
byref(AE::c6); // error: c6 not an lvalue
byref(AE::c7); // ok
const int* p1 = &AE::c6; // error: c6 not an lvalue
const int* p2 = &AE::c7; // ok
std::cout << "p1 " << *p1 << "n";
std::cout << "p2 " << *p2 << "n";
return 0;
}
void byref(const int & a)
{
std::cout << a << "n";
}
暂时忽略Microsoft编译器...
在编译这个程序时,我得到了undefined reference to AE::c6
,在堆栈更改为byref(+AE::c6);
时发现了一个小技巧,可以解决它。
但是对于另一行const int* p1 = &AE::c6;
如注释所示,它将生成一个错误,但事实并非如此(它编译并运行正常(。
所以我有两个问题:
- 这里的一元+角色是什么?
- 为什么编译器忽略了错误
const int* p1 = &AE::c6;
,这与我预期不同?
对于第一个问题,在常量名称前面添加+
会将值从常量更改为表达式。 表达式的结果将存储到一个未命名的临时变量中,并且对该临时变量的引用将传递给byref
。 如果没有+
,则直接引用常量,这要求常量在程序中的某个地方有一个定义。
对于第二个问题,编译器不会在编译期间发出诊断,因为AE::c6
的一个定义可能存在于不同的源文件中。 链接器在找不到定义时会提供错误。
[class.static.data] 中的语言标准说:"在程序中,应该只有一个 odr 使用的静态数据成员的定义 (6.2(;不 需要诊断。 因此,没有定义或有多个定义是一种违规行为,但不需要报告。 在前一种情况下,编译器/链接器可以创建要使用的定义,而在后一种情况下,链接器将只选择一个可用的定义。
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 静态数据成员模板专用化的实例化点在哪里
- 调用在 HXX 文件中声明的静态数据成员
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 错误: 无效使用非静态数据成员"应用程序::应用程序构造函数"
- 静态数据成员:它"const declaration / constexpr definition"起作用?
- 何时需要定义类的静态数据成员 (un/-)
- 为什么静态数据成员不能在c++11中的类中初始化
- 静态数据成员的模板专用化
- 拒绝包含某些公共静态数据成员的类型
- GCC:在调试构建中优化的静态数据成员
- 类模板静态数据成员定义/声明/初始化
- C++ 中的静态数据成员
- 如果类在 C++ 中具有常量或引用类型的非静态数据成员,为什么编译器不提供默认赋值运算符?
- 使用 lambda 函数初始化静态数据成员
- 引用静态数据成员
- 学习C++并在早期示例中遇到错误(在非静态数据成员之前需要构造函数)
- Windows 上的 Clang/LLVM 7 和 8 多次初始化内联静态数据成员(使用 link.exe 和 lld-
- 为什么不能使用"( )"为类的非静态数据成员提供默认值?
- 不带初始值设定项的 constexpr 静态数据成员