An Adventure in Modern C++ Library Design - Robert Leahy - C++Now 2024

Поділитися
Вставка
  • Опубліковано 18 жов 2024
  • www.cppnow.org​
    ---
    An Adventure in Modern Library Design - Robert Leahy - C++Now 2024
    ---
    Library design used to seem easy: Model the problem domain with classes which sometimes inherit from one another, throw in a few free functions, and you’re done. Modern library design is unrecognizable from that frame of reference: Customization point objects, expression equivalence, perfect forwarding, a seemingly-endless list of edge cases and sharp edges understood only by experts.
    This journey from simple to complicated didn’t occur without reason. Putting complexity into libraries transfers that complexity into a single place where it can be dealt with once. Improving genericity by considering and handling edge cases and seemingly-obscure use cases furthers the concentration of complexity by increasing the reach and leverage of C++ libraries.
    This talk will explore modern C++ library design principles using the real-world example of a library which interfaces with a time series database. CPOs and generic algorithms form the foundation of this C++ library. Sophisticated uses of std::variant, CTAD, and immovable types will be introduced. Attendees will gain actionable insights into designing modern C++ libraries to address complex software engineering challenges.
    ---
    Slides: github.com/boo...
    Undo: Debug your hardest C++ bugs with time travel debugging → Learn more at bit.ly/cppnow24
    ---
    Robert Leahy
    Robert is a graduate of the University of Victoria where he specialized in graphics, gaming, and digital geometry processing. After spending 4.5 years in full stack web development he pivoted to financial infrastructure in early 2016 and now works on next generation market data storage and retrieval mechanisms. In 2019 he became involved in the ISO C++ committee with a particular focus on library evolution.
    ---
    C++Now 2025 - 28th April - 2nd May
    C++Now is an annual onsite international C++ programming and coding conference held in Aspen, Colarado. For all C++ developers, C++ software engineers and those involved with the C++ language, CppNow provides an indepth and technical content provided by the best and brightest C++ experts of the C++ world.
    Annual CppNow Conference - www.cppnow.org
    / cppnow​
    / cppnow
    / cppnow
    / cppnow
    mastodon.socia...
    Video Sponsors: millennium and think-cell
    ---
    Videos Filmed & Edited By Bash Films: bashfilms.com/
    UA-cam Channel Managed & Optimized By Digital Medium Ltd: events.digital...
    ---
    #boost #cpp #programming #cppprogramming #cppnow

КОМЕНТАРІ • 6

  • @Qazqi
    @Qazqi Місяць тому +2

    15 seconds in and I'm already being personally attacked. I do, in fact, wake up and decide to write a random library just because my brain thought it would be cool/fun. And then of course don't finish. ADHD is a hell of a drug.

  • @spyofgame200
    @spyofgame200 3 місяці тому +2

    Wow, I watched for an hour and just realized it was released on UA-cam only an hour ago.

  • @SamWhitlock
    @SamWhitlock 2 місяці тому

    36:10 can someone enlighten me about the `void run();` use here? I'm trying to understand what value that adds for the function name lookup

    • @robertleahy6923
      @robertleahy6923 2 місяці тому

      Speaker here.
      When you perform qualified name lookup, for example by typing std::swap in your code, you will call a matching overload of swap which is found in exactly the given scope (in this case std).
      When you perform unqualified name lookup, for example by typing just swap in your code, the search for matching overloads is more interesting. First "regular unqualified name lookup" is performed, which searches for a matching name by looking in enclosing scopes until a match is found.
      So, for example, if you type quux(a) in a function in the namespace foo::bar regular unqualified name lookup will search:
      1. The function body itself, then if no name quux is found
      2. The namespace foo::bar, then if no name quux is found
      3. The namespace foo, and then if no name quux is found
      4. The global namespace
      Note the "then if no name quux is found." If a name quux is found the search stops immediately. So if you have a quux in foo::bar and in foo only foo::bar::quux will be found, foo::quux will not be considered.
      Once regular unqualified name lookup finds a match, if the match is a regular function, then another kind of lookup continues populating the "candidate set" (the set of overloads with the correct name which are found by name lookup): Argument dependent lookup. This lookup tries to find matches in the "associated namespaces" of arguments to the function call. So in this case the namespaces containing:
      - The type of a, and
      - The template arguments used to instantiate the type of a, if any
      Are the associated namespaces. All names quux from those namespaces are then added to the candidate set, and then overload resolution occurs.
      In the example you're talking about we don't want any alternatives which are put in the candidate set by regular unqualified name lookup, we only want names from argument dependent lookup, which means we need to inhibit regular unqualified name lookup somehow.
      The way we do this is add a "poison pill:" The declaration of a function run (without a definition). Within detail::run when regular unqualified name lookup starts searching for a match it will first consider the calling context, and then detail::run. Once it searches inside detail::run it finds a match, our nullary function declaration, and therefore it:
      - Ends regular unqualified name lookup, and since it found a regular function
      - Begins argument dependent lookup
      Note that the latter is what we actually want. Also note that when we call run we call it unary (with one argument) which means the poison pill we found will get ruled out by overload resolution. Therefore while regular unqualified name lookup does occur we manipulate the results it generates so it's as if it doesn't happen, thereby fulfilling the requirements laid out in text/standardese on the slide before.

    • @scarletlettersproductions4393
      @scarletlettersproductions4393 25 днів тому

      When the compiler is figuring out what function is being called, it first calculates the full overload set of possible functions that could be being called by doing:
      1. Qualified lookup, if you made a qualified call (I.e some_namespace::my_function)
      2. Unqualified lookup. Recursive looks in each namespace in the nesting (in this example, it would look in detail::run, then detail, then the global namespace)
      3. Argument dependent lookup. See the standard for the exact rules, but being reductionary, it looks up based on the namespace the type(s) of the argugment(s) were defined in.
      After it does that, it then determines the best match from the overload set it found.
      The void run(); eliminates unqualified lookup when determining that overload set, so that only ADL is used to determine that overload set, effectively limiting the lookup to only ADL