Will consteval allow using static_assert on function arguments?

后端 未结 1 835
耶瑟儿~
耶瑟儿~ 2020-12-10 13:39

Currently you cannot use static_assert to verify parameters of a constexpr function, even if all calls to it are indeed constexpr. Tha

相关标签:
1条回答
  • 2020-12-10 14:09

    Will consteval allow to use static_assert on function arguments?

    No. Function arguments have never been, and will continue to not be, usable as constant expressions.

    There is a difference between something being constant evaluated and being usable as a constant-expression. consteval ensures that we're in a constant evaluation context, but it does not also cause everything to become constant-expressions.

    In order to allow function arguments to be usable as constant expressions, you would need to make everything implicitly a template:

    template <int> struct X { };
    
    consteval auto foo(int i) {
        static_assert(i > 10); // in order to allow this...
        return X<i>{};         // ... you'd have to allow this too
    }
    

    And now foo(20) and foo(30) return different types. That's a template.


    Important background reading for understanding why this is a fundamental and inherent limitation can be found in Andrew Sutton's Translation and evaluation: A mental model for compile-time metaprogramming:

    Having a mental model of compile-time evaluation that physically separates it from the process of translation has been extremely helpful for me. In particular, it has helped me understand what is not possible (e.g., instantiating a template during evaluation). This helps prune the design space for otherwise large and complex language features. Hopefully, others will find this note helpful as well.


    With static_assert specifically though, you can add a workaround just to cause a compilation failure. That's just adding anything at all that can't be used during constant evaluation. Like:

    #define CONSTEVAL_STATIC_ASSERT(c, msg) do { if (!(c)) throw msg; } while(false)
    

    as in:

    consteval char operator""_bchar(const char text[], const size_t length)
    {
        CONSTEVAL_STATIC_ASSERT(length == 8, "Binary char has to have 8 digits!");
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题