为什么在调用此constexpr静态成员函数时不将其视为constexpr? [英] Why is this constexpr static member function not seen as constexpr when called?

查看:93
本文介绍了为什么在调用此constexpr静态成员函数时不将其视为constexpr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么此 constexpr static 成员函数由 //标识! Nah 评论,被调用时不被视为 constexpr

Why is this constexpr static member function, identified by the //! Nah comment, not seen as constexpr when called?

struct Item_id
{
    enum Enum
    {
        size, position, attributes, window_rect, max_window_size, _
    };

    static constexpr int n_items_ = _;                          // OK
    constexpr auto member_n_items() const -> int { return _; }  // OK
    static constexpr auto static_n_items() -> int { return _; } // OK
    static constexpr int so_far = n_items_;                     // OK
    #ifndef OUT_OF_CLASS
        static constexpr int bah = static_n_items();            //! Nah.
    #endif
};

constexpr auto n_ids() -> int { return Item_id().member_n_items(); }    // OK

auto main() -> int
{
    #ifdef OUT_OF_CLASS
        static constexpr int bah = Item_id::static_n_items();   // OK
    #endif
}

MinGW g ++ 5.1报告

MinGW g++ 5.1 reports


constexpr.cpp:12:46: error: 'static constexpr int Item_id::static_n_items()' called in a constant expression
     static constexpr int bah = static_n_items();                //! Nah.

Visual C ++ 2015报告

Visual C++ 2015 reports


constexpr.cpp(12): error C2131: expression did not evaluate to a constant
constexpr.cpp(12): note: failure was caused by call of undefined function or one not declared 'constexpr'
constexpr.cpp(12): note: see usage of 'Item_id::static_n_items'

我的文本编辑器坚持要求调用中的名称相同

My text editor insists that the name in the call is the same as the name in the function definition.

它似乎与不完整的类有关,因为与 OUT_OF_CLASS 定义它可以很好地编译。

It appears to have something to do with incomplete class, because with OUT_OF_CLASS defined it compiles nicely.

但是为什么 n_items _ 数据起作用,为什么这样的规则(确实

But then why does the n_items_ data work, and, why such a rule (doesn't make sense to me)?

推荐答案

从内存中,仅在完全定义了类之后,才对成员函数主体进行求值。

From memory, member function bodies are evaluated only once the class has been completely defined.

static constexpr int bah = static_n_items(); 

构成类定义的一部分,但它引用的是(静态)成员函数,尚不能

forms part of the class definition, but it's referring to a (static) member function, which cannot yet be defined.

解决方案:

将常量表达式推迟为基类并从中派生。

defer constant expressions to a base class and derive from it.

例如:

struct Item_id_base
{
    enum Enum
    {
        size, position, attributes, window_rect, max_window_size, _
    };

    static constexpr int n_items_ = _;                          // OK
    constexpr auto member_n_items() const -> int { return _; }  // OK
    static constexpr auto static_n_items() -> int { return _; } // OK
    static constexpr int so_far = n_items_;                     // OK
};

struct Item_id : Item_id_base
{
    #ifndef OUT_OF_CLASS
        static constexpr int bah = static_n_items();            // now OK
    #endif
};

constexpr auto n_ids() -> int { return Item_id().member_n_items(); }    // OK

auto main() -> int
{
    #ifdef OUT_OF_CLASS
        static constexpr int bah = Item_id::static_n_items();   // OK
    #endif
}




为什么您认为该标准不允许这样做?

Why do you think the standard disallows it?

因为这是非法的:

struct Item_id
{   
    // ... etc.

    #ifndef OUT_OF_CLASS
        static constexpr int bah;// = static_n_items();            //! Nah.
    #endif
};

constexpr int Item_id::bah = static_n_items();

并且constexpr必须具有constexpr定义。

And a constexpr must have a constexpr definition. The only place we can define it is during its declaration...

...所以我们唯一可以定义它的地方是……所以通过推论,它不能引用尚未定义身体的任何函数。

... so by deduction it cannot refer to any function who's body is not yet defined.

我不知所措要知道所有标准在哪里。可能有5个不同的,看似无关的子句:)

I am at a loss to know where to look in the standard for all that. Probably 5 different, seemingly unrelated clauses :)

这篇关于为什么在调用此constexpr静态成员函数时不将其视为constexpr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆