C++ Weekly - Ep 437 - Pointers To Overloaded Functions

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 ส.ค. 2024
  • ☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟
    Upcoming Workshop: C++ Best Practices, NDC TechTown, Sept 9-10, 2024
    ► ndctechtown.co...
    Upcoming Workshop: Applied constexpr: The Power of Compile-Time Resources, C++ Under The Sea, October 10, 2024
    ► cppunderthesea...
    Episode details: github.com/lef...
    T-SHIRTS AVAILABLE!
    ► The best C++ T-Shirts anywhere! my-store-d16a2...
    WANT MORE JASON?
    ► My Training Classes: emptycrate.com/...
    ► Follow me on twitter: / lefticus
    SUPPORT THE CHANNEL
    ► Patreon: / lefticus
    ► Github Sponsors: github.com/spo...
    ► Paypal Donation: www.paypal.com...
    GET INVOLVED
    ► Video Idea List: github.com/lef...
    JASON'S BOOKS
    ► C++23 Best Practices
    Leanpub Ebook: leanpub.com/cp...
    ► C++ Best Practices
    Amazon Paperback: amzn.to/3wpAU3Z
    Leanpub Ebook: leanpub.com/cp...
    JASON'S PUZZLE BOOKS
    ► Object Lifetime Puzzlers Book 1
    Amazon Paperback: amzn.to/3g6Ervj
    Leanpub Ebook: leanpub.com/ob...
    ► Object Lifetime Puzzlers Book 2
    Amazon Paperback: amzn.to/3whdUDU
    Leanpub Ebook: leanpub.com/ob...
    ► Object Lifetime Puzzlers Book 3
    Leanpub Ebook: leanpub.com/ob...
    ► Copy and Reference Puzzlers Book 1
    Amazon Paperback: amzn.to/3g7ZVb9
    Leanpub Ebook: leanpub.com/co...
    ► Copy and Reference Puzzlers Book 2
    Amazon Paperback: amzn.to/3X1LOIx
    Leanpub Ebook: leanpub.com/co...
    ► Copy and Reference Puzzlers Book 3
    Leanpub Ebook: leanpub.com/co...
    ► OpCode Puzzlers Book 1
    Amazon Paperback: amzn.to/3KCNJg6
    Leanpub Ebook: leanpub.com/op...
    RECOMMENDED BOOKS
    ► Bjarne Stroustrup's A Tour of C++ (now with C++20/23!): amzn.to/3X4Wypr
    AWESOME PROJECTS
    ► The C++ Starter Project - Gets you started with Best Practices Quickly - github.com/cpp...
    ► C++ Best Practices Forkable Coding Standards - github.com/cpp...
    O'Reilly VIDEOS
    ► Inheritance and Polymorphism in C++ - www.oreilly.co...
    ► Learning C++ Best Practices - www.oreilly.co...

ความคิดเห็น • 40

  • @flamewingsonic
    @flamewingsonic หลายเดือนก่อน +43

    7:18 Overload macro is referring directly to "callable" instead of the macro parameter.

    • @szaszm_
      @szaszm_ หลายเดือนก่อน +3

      Probably one of the reasons it's not recommended: poor compiler diagnostics, bugs go unnoticed.

  • @Shakephobiaful
    @Shakephobiaful หลายเดือนก่อน +7

    This problem became more prevalent with C++20/23 views (namely transform) and the optional monadic operations, because they encorage us to pass function pointers to small things.
    I worked around it by using template specializations instead of function overloads. The template is deleted for the general case, but specialized for the interesting cases. Then specifying the needed overload is easy.
    For example, consider a function that translates a string to a type of integer. It would be `from_string`.

  • @klausneda8807
    @klausneda8807 หลายเดือนก่อน +13

    Good job Jason, you even got the phishing profiles with booty profile pictures interested in C++ :D

  • @avramlevitter6150
    @avramlevitter6150 หลายเดือนก่อน +2

    I ended up with a similar situation when trying to make projections for use with std::ranges- did you know that taking the address of standard library functions or members of structs is not allowed? And sometimes, the type is very complicated in how it's derived. So I ended up writing macros for calling a member function or for returning a member field. Interesting to see that I'm not the only one with this idea.

  • @aniketbisht2823
    @aniketbisht2823 หลายเดือนก่อน +1

    6:48 With reflections we would be able to replace this with a variable template which would take a reflection of a "function overload set" and turn that into a function object (lambda) which will forward it's arguments to that overload set. Basically we would be able to "objectify" any "free" function template and overload set Ex:
    template
    constexpr auto FuncObj = [](...){....};
    int main(){
    use_callable(FuncObj);
    }

  • @weker01
    @weker01 27 วันที่ผ่านมา

    I mean it makes sense that the compiler will complain that you are trying to use (but cannot instantiate yourself) a template with a template parameter that cannot be defined in another compilation unit. The current compilation unit would not even emit code for any call operator template of the lambda and no other CU can ever emit code for it as it is undefineable there.
    It would compile if one defines a struct like you did with the Lambda, as this struct is something that theoretically could be defined in another CU. (For example if the Lambda struct was in a header). If it actually is still not known in any other CU or nobody instantiate use_callable with the Lambda struct than the linker would complain in the end.

  • @aniketbisht2823
    @aniketbisht2823 หลายเดือนก่อน +1

    As soon as I read the title, I was like, "LAMBDAS!".

  • @idiotsiuda
    @idiotsiuda หลายเดือนก่อน +2

    I ask to make a video with overloaded member functions references in the same format as this video.

    • @cppweekly
      @cppweekly  หลายเดือนก่อน +1

      I keep track of all the topic requests in one place so I don't lose them. Feel free to add your request to the list: github.com/lefticus/cpp_weekly/issues/

  • @robikz
    @robikz หลายเดือนก่อน +1

    I'm working with an older Qt, and the QNetworkReply there has an error() getter method and an error(Error) signal. I wanted to connect this signal to a slot using the "new" method pointer syntax, instead of the old Qt's SIGNAL macro, but the errors the compiler gave me made me end up using the SIGNAL macro anyway. So, now all the connects all around use the method pointers, but this one is the old SIGNAL / SLOT pair, haha. And this happened like two days ago.

    • @sledgex9
      @sledgex9 หลายเดือนก่อน +2

      I swear that the old qt docs about the 2 different signal/slot syntaxes mentioned a way to deal with overloaded signals or slots. But I can't find it. All I can find is a SO answer that points to the "qOverload()" helper funtion. Or just use a static cast to help the compiler, and use the new syntax which offers type safety with no runtime overhead.

    • @robikz
      @robikz หลายเดือนก่อน +2

      @@sledgex9 Well, I'll be damned, it was `connect(reply, static_cast(&QNetworkReply::error), this, &WebQuery::onError);` all along.

  • @paulfee9839
    @paulfee9839 หลายเดือนก่อน +3

    I find this approach somewhat less disappointing as it avoids static casts.
    void (*selected_overload)(double) = callable;
    use_callable(selected_overload);

    • @weker01
      @weker01 27 วันที่ผ่านมา

      It is fundamentally the same though. Do you mean you like the syntax better?

    • @paulfee9839
      @paulfee9839 24 วันที่ผ่านมา

      @@weker01 Yes, the syntax feels better. However it's two steps, so isn't ideal when you want to pass the callable to an STL algorithm without extra baggage.

  • @dadisuperman3472
    @dadisuperman3472 หลายเดือนก่อน

    --Consider the following case:
    template
    void foo(int){}
    --a simple function template.
    --that doesn't use the template parameters anywhere in its arguments or return type.
    Yet, If you try to pass it as a pointer, the compiler will complain about overload ambiguity.
    -- so if you say for example
    auto fooPtr = &foo;
    -- this is a compiler error.
    -- to correct it we write.
    auto fooPtr = &foo;
    -- that means the template parameter participate in the overload resolution despite it is not used anywhere in the function signature!!!
    Question for smart people here.
    Imagine you have been passed a function pointer to foo, how can you tell which type was used in the template argument when instantiating the function??

    • @cppweekly
      @cppweekly  27 วันที่ผ่านมา

      In this example: compiler-explorer.com/z/bneh55aG6
      The information is completely lost inside of "use_func" but possible to object from inside of "func" and possible from the context of "main"
      It's an interesting point, and you can see it play out when you look at the mangled names of the functions.
      I don't think that even reflection would help, because inside of "use_func" you only have a function pointer, and these things could be defined in different shared libraries compiled at different times.

  • @r75shell
    @r75shell หลายเดือนก่อน

    Interesting question follows from it: does &callable has value and type? Or is it quantum object? (:

  • @cmdlp4178
    @cmdlp4178 หลายเดือนก่อน

    The C++ Standard could do it much much better regarding functions. Namely, instead of "implicitly converting" the "function name" directly to a function pointer it could effectively create a lambda which contains all overloads of the function. This might be very useful for the standard algoritms/ranges. For example consider applying transform(abs) to a range, of course this should work with floats, ints and other number types. Usually the pattern with surrounding the function with a lambda (Like with the macro) achieves exactly what I would like to see implicitly in the standard. Optionally, the standard could add a syntax like using a special unary operator like transform(~sum), as a parallel to the + operator for lambdas

    • @N....
      @N.... หลายเดือนก่อน +3

      Another comment on this video pointed out the proposal P3312 R0 Overload Set Types, which seems to do what you suggest.

  • @BenjaminWheeler0510
    @BenjaminWheeler0510 หลายเดือนก่อน

    I'm starting to think that compilers are secretly magic.

  • @ChristopherSamuelson5
    @ChristopherSamuelson5 หลายเดือนก่อน

    Feels like an oversight. Any known efforts to help make this nicer to work with?

    • @cppweekly
      @cppweekly  27 วันที่ผ่านมา +1

      Not that I know of, no.

  • @toddfulton2280
    @toddfulton2280 หลายเดือนก่อน +1

    Any thoughts on P3312 R0 Overload Set Types?

    • @N....
      @N.... หลายเดือนก่อน +2

      Interesting! It makes some pain points easier but I don't think we'll have a proper way to handle overload sets and template functions in a generic way until reflection is in the language unfortunately. The inability to extract type information from template functions without instantiating them is particularly bothersome.

    • @toddfulton2280
      @toddfulton2280 หลายเดือนก่อน +1

      @@N.... Yeah, there is p2996, which seems to be getting some traction, though with some debate around the define_class interface and code injection:
      P3294 R0 Code Injection with Token Sequences

    • @cppweekly
      @cppweekly  27 วันที่ผ่านมา +2

      I wasn't aware of it, I'll take a look.

  • @kethernet
    @kethernet หลายเดือนก่อน

    Seems to me it would be trivial for the standard to allow an overload set to automatically translate into a lambda that has operator() overloads for everything in the overload set. I think this would be useful, or are there downsides I'm not seeing?

    • @AruisDante
      @AruisDante หลายเดือนก่อน

      The problem is sometimes you actually want the function pointer. Without adding a new keyword, there’s no easy way in the existing syntax to disambiguate “I want exactly this name” from “I want the set of things with this name.”
      Reflection in 26 should, I think, make writing the OVERLOAD helper without a macro possible, but I’m not 100%, as it may require the injection features we haven’t gotten yet.

    • @kethernet
      @kethernet หลายเดือนก่อน

      @@AruisDante Nothing that currently is a function pointer would become a lambda object. If currently using an overload set results in an error, is it really a problem if in the future it would result in a usable object instead? I don't think there would be a need to change the behavior of any existing code that compiles.

    • @aniketbisht2823
      @aniketbisht2823 หลายเดือนก่อน

      @@AruisDante We won't need injection feature because we only need to reflect overload set as meta::info object and pass it as template parameter and then reify it in the lambda body.

  • @AtomicAndi
    @AtomicAndi หลายเดือนก่อน +1

    Raw function pointers are arguably a code smell

  • @sigasigasiga
    @sigasigasiga หลายเดือนก่อน +4

    so sad that you haven't covered all the complications one may go through to implement the most perfect lambda wrapper for an overloaded function: `constexpr`, `noexcept`, `static`, `requires`