以下内容如何在gcc上起作用而在clang(see it live)上不起作用:

constexpr int giveMeValue() { return 42; }

struct TryMe {
  static constexpr int arr[1] = {
      giveMeValue()
  };
};

int main() {
    int val = TryMe::arr[0];
    return val;
}

我收到了带有lang的 Unresolved external symbol 。
TryMe::arr[0]是一个对象吗?如果是,是否已使用?

最佳答案

TryMe::arrodr-used,但您未提供定义(see it live):

constexpr int TryMe::arr[1];

为什么gccclang之间的结果不一致?这是因为从C++ 11和C++ 14草案标准(强调我的观点)来看,违反odr并不需要不确定性:



我们可以看到它在C++ 11标准草案的3.2部分中被奇怪地使用,它说:


TryMe::arr是一个对象,它确实满足出现在常量表达式中的要求,但是左值到右值的转换不会立即应用于TryMe::arr,而是会立即应用于TryMe::arr[0]

C++ 14标准草案中的更新措辞也适用于C++ 11,因为它是通过缺陷报告(DR 712)应用的:



根据TryMe::arr[0]段落3.2中的条件,表达式2的潜在结果为空,因此可以使用。

注意:您需要按照9.4.2 [class.static.data]部分的说明在类外提供一个定义,该定义为(强调我的):



更新

T.C.指出了defect report 1926,它在3.2 [basic.def.odr]第2段中添加了以下项目符号:



这意味着对数组下标不再是odr的用法,因此OPs代码将在C++ 1z中格式正确,并且看起来像C++ 14,因为缺陷看起来像针对C++ 14。

关于c++ - 是否使用了静态constexpr?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26196095/

10-09 03:25