-
Notifications
You must be signed in to change notification settings - Fork 261
UFCS try to get pointer using get() after other matches failed #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UFCS try to get pointer using get() after other matches failed #13
Conversation
90cd42d
to
e8a48b9
Compare
On MacOSX 12.3 SDK there is no <memory_resource> header there is <experimental/memory_resource> - check with __has_include to include existing one. There was no <cuchar> and <stop_token> - add checking if it is present.
In example of using fopen the code looks like: main: () -> int = { myfile := fopen("file-opened-with-c-function.txt", "w"); myfile.fprintf("Unified Function Call Syntax Rocks!\n\n"); myfile.fclose(); } there is a need to call fclose at the end of scope. We can introduce better_fopen that will return unique_prt with fclose as a deleter. main: () -> int = { myfile := better_fopen("file-opened-with-c-function.txt", "w"); myfile.fprintf("Unified Function Call Syntax Rocks!\n\n"); } That will ensure closing but will not work with UFCS. In this change we added a check (after other matches failed) if there is a call to get() method that match a function signature.
e8a48b9
to
4cd6e71
Compare
Is this just a convenience for not having to write: myfile.get().fprintf("Unified Function Call Syntax Rocks!\n\n"); ? I don't think I feel super good about the language letting us pass invisibly the raw pointer of a smart pointer to a function. That function could be making and storing copies of the pointer, all the while on the calling side everything looks safe. |
On the other hand, C++ already allows: void buggy_function(const std::unique_ptr<T>& i_look_fine_to_the_caller) {
T* = i_look_fine_to_the_caller.get();
...
} so 🤷 |
@jcanizales I made that before #17. I still thinks that it is worth experimenting with |
Thanks -- I agree with a way to automate the I would try an RAII wrapper, perhaps something that could be used like this:
I think I've seen such little wrapper libs floating around the internets but I can't find one just now... here's a very rough cut at it:
Then
And you get:
DISCLAIMERS:
So while I've engaged on this suggestion, everyone please do accept my apologies in advance to many other suggestions that I'm surely going to answer with "I honestly do think that's an interesting idea, but I'm saying no to spending time on it (as with a number of my own such interesting ideas!) because I need to stay disciplined and focus only on quantifiable simplicity/safety/toolability improvements right now" -- thanks in advance for understanding. |
Doesn't |
They're related but not quite the same. A major difference is that you can't easily store a |
The second disclaimer is worth adding as a "suggestion" template issue. |
@hsutter Please look at #17 and #18 - it is about chaining function calls that allow you to write: #include <vector>
#include <memory>
template <typename T, typename R>
auto on_scope_exit(T* f, R(*close)(T*)) {
return std::unique_ptr<T, decltype(close)>{f, close};
}
main: () -> int = {
f2 := fopen("variable2.txt", "w").on_scope_exit(fclose);
f2.get().fprintf("you can handle smart_ptrs without changing behaviour of UFCS");
m := fopen("manual.txt", "w");
m.fprintf("Manual handling still works");
m.fclose();
} I agree that my first proposal was too magical. After that, I have been experimenting more with cppfront and after implementing function chaining I realize that it allows adding a call to I guess that function chaining is a better solution to my original problem and it could go further: visit: (in v:_, in callable:_) -> auto = {
return callable(v);
}
main: () -> int = {
fopen("one_liner.txt", "w").on_scope_exit(fclose).get().visit(:(e:_) = {
e.fprintf("1) This is oneliner!!\n\n");
e.fprintf("2) This is oneliner!!\n\n");
e.fprintf("3) This is oneliner!!\n\n");
e.fprintf("4) This is oneliner!!\n\n");
e.fprintf("5) This is oneliner!!\n\n");
e.fprintf("6) This is oneliner!!\n\n");
});
} |
Great suggestion. Done, thanks. |
The current implementation of UFCS is not handling smart pointers well. For example, using fopen the code looks like this:
there is a need to call fclose at the end of the scope. We can introduce
better_fopen
that will returnunique_prt
withfclose
as a deleted.That will ensure closing but will not work with UFCS.
In this change, I have introduced an additional check (after other matches failed) if there is a call to the
get()
method that matches a function signature. If yes then the underlying raw pointer is taken usingget()
method and used to match function syntax.