繁体   English   中英

在C ++中使用同一类的另一个方法中的constexpr方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM