C++ Logo

std-proposals

Advanced search

Re: [std-proposals] noexcept has gotten a bit hairy -- I want a compiler error

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sun, 4 May 2025 18:20:26 +0100
On Sat, May 3, 2025 at 7:10 PM Frederick Virchanza Gotham wrote:
>
> This is a very premature half-baked idea that popped into my head just
> now . . .


And I was also thinking that we should have a cast for adding or
removing 'noexcept' from a function pointer, perhaps calling it
'noexcept_cast', and it should be constexpr.

Presently here's how I'm doing it:

    #include <cstring>

    template<bool bFrom, typename T> struct NoExceptFromTrue {};
    template<bool bFrom, typename T> struct NoExceptFromFalse {};

    template<bool bTo, typename R, typename... Params>
    struct NoExceptFromTrue < bTo, R(*)(Params...) noexcept(true ) > {
using type = R (*)(Params...) noexcept(bTo); };
    template<bool bTo, typename R, typename... Params>
    struct NoExceptFromFalse< bTo, R(*)(Params...) noexcept(false) > {
using type = R (*)(Params...) noexcept(bTo); };

    template<bool bTo, typename R, typename Class, typename... Params>
    struct NoExceptFromTrue < bTo, R(Class::*)(Params...) noexcept(true ) > {
        using type = R (Class::*)(Params...) noexcept(bTo);
    };

    template<bool bTo, typename R, typename Class, typename... Params>
    struct NoExceptFromFalse< bTo, R(Class::*)(Params...) noexcept(false) > {
        using type = R (Class::*)(Params...) noexcept(bTo);
    };

    template<bool b, typename T>
    auto noexcept_cast(T const arg)
    {
        if constexpr ( requires { typename NoExceptFromTrue<b, T>::type(); } )
        {
            using Tto = typename NoExceptFromTrue<b, T>::type;
            return *static_cast<Tto const *>(static_cast<void const*>(&arg));
        }
        else
        {
            using Tto = typename NoExceptFromFalse<b, T>::type;
            return *static_cast<Tto const *>(static_cast<void const*>(&arg));
        }
    }

    int mystrlen1(char const *) { return 8; }
    int mystrlen2(char const *) noexcept { return 8; }
    int mystrlen3(char const *) noexcept(false) { return 8; }

    int main(int const arg, char **const argv)
    {
        auto func1 = noexcept_cast<true>( &mystrlen1 );
        auto func2 = noexcept_cast<true>( &mystrlen2 );
        auto func3 = noexcept_cast<true>( &mystrlen3 );
        auto func4 = noexcept_cast<true>( &std::strlen );
        return func1( argv[0] ) + func2( argv[0] ) + func3( argv[0] )
+ func4( argv[0] );
    }

But I can't make it constexpr. Here's the GodBolt:
https://godbolt.org/z/1b6qK6avo

Maybe we should have either an operator, 'noexcept_cast', or a
standard library function, 'std::noexcept_cast'.

Received on 2025-05-04 17:20:36