[英]Using a constexpr method inside another method of the same class in C++
正如所料,我可以毫无问题地编译下面的示例
// first_sample.cpp
struct sample_struct
{
constexpr int
sample_method()
{ return 5; }
};
int main()
{
sample_struct sample_object;
constexpr int sample_variable = sample_object.sample_method();
return 0;
}
但我无法编译以下示例
'这'不是一个恒定的表达
// second_sample.cpp
struct sample_struct
{
constexpr int
sample_method_first()
{ return 5; }
void
sample_method_second()
{ constexpr int sample_variable = sample_method_first();
/* Do something with sample_variable */ }
};
int main()
{ return 0; }
我已经知道如何解决这个“问题”所以我不是要求解决方案。 我要求一个合理的解释为什么我被允许从非constexpr对象调用constexpr方法, 而我不允许在另一个方法中调用相同的constexpr方法(来自非constexpr'this')。
在C ++标准中,[dcl.constexpr] / 9:
对象声明中使用的constexpr说明符将对象声明为const。 这样的对象应具有文字类型并应初始化。 [...]否则,或者如果在引用声明中使用constexpr说明符,则其初始值设定项中出现的每个完整表达式都应为常量表达式。
现在,编译器隐式地将this->
添加到成员函数调用中,由[expr.call] / 1指定
在隐式类成员访问的情况下,隐含的对象是由此指向的对象。 [注意:形式为
f()
的成员函数调用被解释为(*this).f()
(见9.3.1)。 - 尾注]
正如jogojapan指出的那样(参见聊天讨论 ),在官方的C ++ 11标准中, this
可能在类成员访问中作为postfix-expression出现,如[expr.const] / 2所示,这就是这里的情况。 但问题1369的决议不允许在不断表达中使用this
; 然而功能调用取代可以允许使用this
一范围内constexpr
通过用prvalue指针代替它的功能。
在C ++ 14草案去除分段约函数调用置换赞成异常的为[expr.const] / 2,明确地允许使用this
一范围内constexpr
函数(在这种情况下,实际上是相同的允许什么函数调用替换)。
嗯,这不是很“合理”,因为它没有提供以这种方式指定的原因,它只提供了编译器拒绝它的原因。
constexpr
函数可以在任何上下文中调用,是否为常量表达式。 (而且你的sample_method_second
甚至不是constexpr
。)但是必须在编译时评估constexpr
对象。
那么sample_method_second
作用是要求编译器在编译时使用this
来获取sample_method_first
的结果。 显然这是不可能的。
不同之处在于,在第一个示例中, main
的范围允许编译器在sample_object
上调用该方法。 但是能够评估一个对象的值并不会扩展到程序中的所有潜在对象,这就是sample_method_second
所做的。
解决方案(除了使用static
使sample_method_first
独立this
)不是将sample_variable
声明为constexpr
。 如果你以一种需要constexpr
的方式使用它,那么你的设计是有缺陷的,因为一个成员函数实际上需要在最终程序中实现多个(可能是无限的)实现。
请记住,合法constexpr
变量的每个潜在的不同值可能会产生新的模板实例化,不同组织的switch
,或者使用static_assert
停止编译。 尝试在运行时追溯执行!
至于为什么允许第一种情况:
sample_struct sample_object;
constexpr int sample_variable = sample_object.sample_method();
这里发生的是constexpr
函数调用,其规则排除在外
- 为文字类,constexpr函数或简单析构函数的隐式调用调用除constexpr构造函数之外的函数(12.4)
根本没有要求对象是constexpr
因为如果某些东西需要是常量来评估函数的内部,或者使用函数的结果,那么评估将根据其他规则(如左值)进行评估。到左值转换。 您将无法修改sample_method
实际访问任何东西,这样做会抱怨sample_object
未声明constexpr
,或它的地址是不恒定的,如果你尝试使用的价值this
直接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.