What is Allowed in a constexpr Function?

前端 未结 1 710
予麋鹿
予麋鹿 2020-12-08 05:28

constexpr functions are not supposed to contain:

A definition of a variable of non-literal type

But in this answer a lambda is d

相关标签:
1条回答
  • 2020-12-08 05:37

    It's virtually guaranteed that if there's a discrepancy gcc has the correct behavior, because Visual Studio 2015 doesn't support c++14's extension of constexpr: https://msdn.microsoft.com/en-us/library/hh567368.aspx#C-14-Core-Language-Features

    C++11 constexpr functions

    The function body can only contain:

    • null statements (plain semicolons)
    • static_assert declarations
    • typedef declarations and alias declarations that do not define classes or enumerations
    • using declarations
    • using directives
    • exactly one return statement

    So c++11 cannot tolerate the definition of decltype(div(T{}, T{})) x{}. It would however be acceptable to roll the ternary suggested here in a constexpr function to achieve the same results:

    template <typename T>
    constexpr auto make_div(const T quot, const T rem)
    {
        using foo = decltype(div(T{}, T{}));
                             
        return foo{1, 0}.quot != 0 ? foo{quot, rem} : foo{rem, quot};
    }
    

    Live Example

    C++14 constexpr functions

    The function body may contain anything but:

    • an asm declaration
    • a goto statement
    • a statement with a label other than case and default
    • a try-block
    • a definition of a variable of non-literal type
    • a definition of a variable of static or thread storage duration
    • a definition of a variable for which no initialization is performed

    Where a "Literal Type" is defined here, specifically for objects though, they may be aggregate types with a trivial destructor. So div_t definitely qualifies. Thus c++14, and by extension gcc, can tolerate the definition of decltype(div(T{}, T{})) x{}.

    C++17 constexpr functions

    C++17 added support for closure types to the definition of "Literal Type", so I find it strange that both gcc and Visual Studio support the use of the lambda in the return statement. I guess that's either forward looking support or the compiler chose to inline the lambda. In either case I don't think that it qualifies as a c++14 constexpr function.

    [Source]

    0 讨论(0)
提交回复
热议问题