未定义的静态焦炭引用[]

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

如果我使数组成为非成员,那么它将编译。怎么回事?

// .hpp
struct foo {
  void bar();
  static constexpr char baz[] = "quz";
};

// .cpp
void foo::bar() {
  std::string str(baz); // undefined reference to baz
}
提问于
用户回答回答于

添加到CPP文件中:

constexpr char foo::baz[];

理由:你必须提供定义静态成员以及声明。声明和初始化器在类定义中,但是成员定义必须是分开的。

用户回答回答于

在C++11中,我们不需要为一个静态conexpr成员提供名称空间范围定义,如果它不是ODR-使用,我们可以从C++11标准草稿中看到这一点。

可以在类定义中使用conexpr说明符声明文字类型的静态数据成员;如果是这样,则其声明应指定一个大括号或相等的初始化器,其中作为赋值表达式的每个初始化器-子句都是一个常量表达式。注:在这两种情况下,成员都可能以常量表达式出现。如果使用ODR(3.2),则仍应在名称空间范围内定义该成员(3.2)。在程序和命名空间范围定义中,不应包含初始化器。

所以问题是bazODR-使用在此:

std::string str(baz); 

还需要一个名称空间范围定义。

那么,我们如何确定变量是否是ODR-使用是吗?

除非表达式是未计算的操作数(第5条)或其子表达式,否则表达式可能被计算。一个变量,其名称显示为一个潜在的求值表达式。是否使用ODR-除非它是一个对象满足在常量表达式中出现的要求(5.19)和立即应用lvalue-rvalue转换(4.1)。

所以baz会产生一个常数表达式lvalue-to-rvalue转换不立即应用,因为它不适用于baz作为一个数组。本

一个非函数的极大值(3.10),非数组型T可以转换为一个prvalue。

数组指针转换

扫码关注云+社区