考虑以下功能:
Listener
在使用clang 6.0以及-std = c ++ 17进行编译时,此函数无法编译,因为数组上的size成员函数由于是引用而不是constexpr。错误消息是这样的:
错误:非类型模板参数不是常量表达式
当参数不是 引用时,代码将按预期工作。
我想知道为什么会这样,因为size()实际上返回了模板参数,因此几乎不可能再是const了。该参数是否为引用都无济于事。
我知道我当然可以使用S1和S2模板参数,该功能只是问题的简短说明。
标准中有什么吗?令我惊讶的是编译错误。
答案 0 :(得分:3)
表达式e是核心常量表达式,除非按照抽象机的规则对e的求值将对以下表达式之一求值:
- ...
- 一个 id-expression ,它引用引用类型的变量或数据成员,除非引用具有前面的初始化且
- 它可用于常量表达式或
- 其寿命始于e的评估;
- ...
您的参考参数没有预先初始化,因此无法在常量表达式中使用。
您可以在此处直接使用S1 + S2
。
答案 1 :(得分:3)
有关此问题的报告了一个错误,标题为numpy.ma
。
其中的讨论指出这并不是一个错误。
除非对e求值,否则表达式e是核心常数表达式。 e,遵循抽象机的规则,将评估以下内容之一 以下表达式:
- [...]
- 引用引用类型的变量或数据成员的id表达式,除非引用具有前面的初始化和 要么
- 使用常量表达式或
进行初始化- 其寿命始于e的评估;
- [...]
以上引文摘自n4659草案的[expr.const] /2.11,并强调了重点。
答案 2 :(得分:0)
不幸的是,该标准指出,在类成员访问表达式中,对点或箭头之前的后缀表达式进行了评估; 63 [expr.ref]/1。后缀表达式是a
中的a.b
。该注释真的很有趣,因为这里就是这种情况:
63)如果评估了类成员访问表达式,则即使不需要确定整个后缀表达式的值(例如,如果id表达式表示静态成员),也将进行子表达式评估。
所以data
也会被求值,即使常量表达式的规则也适用于它。