Why is this constexpr static member function not seen as constexpr when called?

前端 未结 2 1733
猫巷女王i
猫巷女王i 2020-12-11 00:44

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

2条回答
  •  粉色の甜心
    2020-12-11 01:18

    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.

    Solution:

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

    e.g.:

    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?

    Because this is illegal:

    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();
    

    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.

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

提交回复
热议问题