Mine is that the useState hook is an actual plague on the entire React ecosystem. Regardless of your opinions of React, if you wanna use something then use it right.

  • TheMightyCat@ani.social
    link
    fedilink
    arrow-up
    3
    arrow-down
    1
    ·
    11 days ago

    It was a simplified example.

    B and C can’t share any other attributes without duplication of code

    struct A {
        [[nodiscard]] virtual std::uint32_t DoSomething() = 0;
    };
    
    struct B : A {
        std::uint32_t DoSomething() override { 
            return 0;
        }
    };
    
    int main() {
        B b;
        b.DoSomething(); //no warning
    }
    

    even if you use virtual attributes aren’t inherited.

    If you ment members instead of attributes this is unrelated to virtual:

    struct A {
        std::uint32_t a;
    };
    
    
    struct B : A {
        void DoSomething() { 
            std::println("B"); 
        }
    };
    
    struct C : A {
        void DoSomething() { 
            std::println("C"); 
        }
    };
    

    Now the member is shared and it works fine and there is no virtual.

    There’s also no strict enforcement of inheritance.

    True, but neither is there when just using virtual:

    struct A {
        virtual void DoSomething() = 0;
    };
    
    struct B : A {
    
    };
    

    This compiles fine if final is not added.

    Not that its an issue as reflection has solved this problem:

    consteval std::string_view HasMethods(std::meta::info impl, std::meta::info iface) {
        constexpr auto ctx = std::meta::access_context::unchecked();
        for (auto fn : members_of(iface, ctx)) {
            if (!is_function(fn) || is_special_member_function(fn)) continue;
            bool found = false;
            for (auto cand : members_of(impl, ctx))
                if (is_function(cand) && has_identifier(cand) && identifier_of(cand) == identifier_of(fn) && type_of(cand) == type_of(fn))
                    found = true;
            if (!found)
                return std::define_static_string(std::string(identifier_of(impl)) + " is missing " + display_string_of(fn));
        }
        return {};
    }
    
    
    struct A {
        void DoSomething();
    };
    
    struct B  {
    
    };
    static_assert(HasMethods(^^B, ^^A).empty(), HasMethods(^^B, ^^A));
    
    // g++ -std=c++26 -freflection main.cpp
    // main.cpp:30:41: error: static assertion failed: B is missing void A::DoSomething()
    // 30 | static_assert(HasMethods(^^B, ^^A).empty(), HasMethods(^^B, ^^A));
    

    Now you get the strict enforcement of inheritance and no virtual.

          • TheMightyCat@ani.social
            link
            fedilink
            arrow-up
            1
            arrow-down
            1
            ·
            11 days ago

            How is it jank to put one utility function in a file somewhere you never need to look at again?

            That is if you even want to do the assert since if the type doesn’t have the method it won’t compile in the calling function anyway but since you mentioned the strict check it’s fully possible.

            And why isn’t it jank to write virtual, final, and override everywhere and have the entire codebase infested with vtables.