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.

  • SpaceNoodle@lemmy.world
    link
    fedilink
    arrow-up
    2
    arrow-down
    1
    ·
    6 days ago

    B and C can’t share any other attributes without duplication of code. There’s also no strict enforcement of inheritance.

    • TheMightyCat@ani.social
      link
      fedilink
      arrow-up
      3
      arrow-down
      1
      ·
      6 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
              ·
              6 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.