相关疑难解决方法(0)

C++ 14:从参数值初始化constexpr变量

假设我有一个可以通过constexpr函数返回常量表达式的类:

template<int N>
struct Foo {
  constexpr int Bar() const { return N; }
};
Run Code Online (Sandbox Code Playgroud)

如果我想初始化constexpr值Foo::Bar(),我应该如何传递类型的参数Foo?我已经尝试了这两个,constexpr每个都有一个示例变量来测试它是否可以初始化:

template<int N>
constexpr int ByValue(Foo<N> f) {
  constexpr int i = f.Bar();
  return f.Bar();
}

template<int N>
constexpr int ByReference(const Foo<N> &f) {
  constexpr int i = f.Bar();
  return f.Bar();
}

constexpr int a = ByValue(Foo<1>{});
constexpr int b = ByReference(Foo<1>{});
Run Code Online (Sandbox Code Playgroud)

但是clang 3.7引发了一个错误,ByReference而gcc> = 5.1则没有:现场演示

main.cpp:15:25: error: constexpr variable 'i' must be initialized …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang constexpr c++14

9
推荐指数
1
解决办法
955
查看次数

[expr.const] 部分中“前面的初始化”一词的含义是什么

constexpr int func(int const& rf){
    return rf;
}
int main(){
   constexpr int value = func(0);
}
Run Code Online (Sandbox Code Playgroud)

考虑上面的代码,变量value应该由一个常量表达式初始化,即func(0),它首先应该是一个核心常量表达式。为了判断表达式是否func(0)是核心常量表达式,将应用以下规则,即:
expr.const#2.7

表达式 e 是核心常量表达式,除非对 e 的求值遵循抽象机的规则,将求值以下表达式之一:

左值到右值的转换,除非它应用于

[...], 或者

(2.7.4) 文字类型的非易失性泛左值,指的是其生命周期开始于 e 求值期间的非易失性对象;

尽管lvalue-to-rvalue conversion应用了rf并且这种转换满足了要点(2.7.4),但是,请看一下下一段,即:
expr.const#2.11

引用引用类型的变量或数据成员的 id 表达式,除非引用具有前面的初始化并且

  • (2.11.1) 它用常量表达式初始化,或者,
  • (2.11.2) 其生命周期开始于 e 的评估内;

我不知道这句话的真正preceding initialization含义是什么?这是否意味着变量应该在使用之前进行初始化,或者意味着在变量的声明中应该有一个初始值设定项。无论如何,在将 应用于lvalue-to-rvalue conversion glvalue之前rf,应该评估 glvaluerf以确定对象的身份,该身份由以下规则决定:

左值是一个表达式,其计算确定对象、位域或函数的标识。

这意味着不仅应遵守项目符号 [expr.const#2.7],还应遵守 [expr.const#2.11]。

因为 id-expressionrf是引用类型。因此,为了使表达式func(0)成为核心常量表达式,id-表达式rf必须有一个前置的初始化 …

c++ language-lawyer constant-expression c++17

5
推荐指数
1
解决办法
213
查看次数

什么是C++ 11标准中的核心常量表达式?

core constant expression在C++ 11标准(N3690)的最新草案中有11个对表达式的引用,它们都没有定义这个实体是什么.

人们还可以发现这里的表达式core constant expression定义很好,基本上与标准用于定义表达式的术语相同.conditional-expression

因此,我想在这个问题上获得一些意见,在我看来,这个问题在标准中是错误的.

现在,假设cppreference中的定义是正确的,我还想知道为什么下面的代码片段在ColiruIdeone中编译,尽管在提到的定义中有第(10)项?

#include <iostream>

int main()
{
    const double x = 2.;
    constexpr double y = x;
    std::cout << y << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我特别考虑表达式中lvalue to rvalue implicit conversion的变量,而上述第(10)项中的任何条款(a),(b)和(c)都没有涵盖这一点.xconstexpr double y = x;

谢谢您的帮助.

c++ language-lawyer constant-expression c++11

4
推荐指数
1
解决办法
574
查看次数