-
Notifications
You must be signed in to change notification settings - Fork 260
[SUGGESTION] Add the equivalent of C++23 "deducing this" #1197
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
Comments
Instead of making special syntax, would
get: (forward this) -> forward T = {...}
Work instead?
On 1 August 2024 07:43:48 Neil Henderson ***@***.***> wrote:
For the same motivations as in P0847<https://wg21.link/p0847>, I'd like to be able to write the equivalent of the "deducing this" feature in Cpp2.
Here's one example where the feature would prevent duplicating code:
my_optional: <T> type = {
has_value: bool = false;
value: T;
get: (in this) -> forward T = { assert(has_value); return value; } // return const-ref
get: (inout this) -> forward T = { assert(has_value); return value; } // return mutable-ref
get: (move this) -> move T = { assert(has_value); return value; }
}
Instead I'd like to write the get function once, with some kind of equivalent "deducing this" syntax that takes care of the this parameter and also the return type, e.g. along the lines of:
get: <Self>(Self _ this) -> _ = { assert(has_value); return value; }
The lowered C++ could duplicate the functions if it's targeting C++20, since the C++23 "deducing this" syntax won't be available.
If, in the future, cppfront supports some kind of cpp_standard flag (like proposed in #942<#942>) then the lowered code for C++23 could use the real "deducing this" feature.
Will your feature suggestion eliminate X% of security vulnerabilities of a given kind in current C++ code?
No
Will your feature suggestion automate or eliminate X% of current C++ guidance literature?
Yes, in the same way that "deducing this" does for C++.
—
Reply to this email directly, view it on GitHub<#1197>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AALUZQJCH6Z2XOHDTYCBARTZPHKKDAVCNFSM6AAAAABLZ4LXS2VHI2DSMVQWIX3LMV43ASLTON2WKOZSGQ2DCNRSGEZDGMA>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Absolutely, I don't mind what the syntax is, as long as it can lower either to C++23 deducing this or C++20 manually stamping out the variations. Here's another idea: get: (deducing this) -> _ = {...} 😆 |
@bluetarpmedia Just to be sure: are you saying that we can't use the "deducing this" feature as of now, or are you just advocating for a more direct and explicit syntax to ease the use of the feature? Btw, I really like your proposed syntax. It doesn't get more explicit than that 😂
|
Currently cppfront lowers to C++20 so to the best of my knowledge there's no way to write Cpp2 that emits the C++23 "deducing this" feature, nor emits the various overloads to simulate it in C++20. |
What we did for |
I think the syntax for explicit object parameter (deducing this) could simply be used whenever
lowered to
Then any use of As for detection we could simply use the feature-test macro |
What I have is more of a question. As far as I understand, the deduplication of cpp code due to deducing this is because we can do perfect forwarding with the 'this' parameter. get: (forward this) -> forward T = {...} |
Thanks for the suggestions! For a It's easy enough to still allow code in the function body to consistently write Here's an adaptation of the first two examples from cppreference, which I think covers the core use cases... // C++23
//
struct X {
template<typename Self>
void foo(this Self&& self, int) {
do_something_with( self );
}
};
struct D : X {};
void ex(X& x, D& d) {
x.foo(1); // Self = X&
move(x).foo(2); // Self = X
d.foo(3); // Self = D&
} Note that Cpp2 already makes // Possible Cpp2?
//
X: @struct type = {
foo: (forward this) = {
do_something_with( this );
}
};
D: type = {
this: X;
}
ex: (inout x: X, inout d: D) = {
x.foo(1); // typeof(this) = X&
move(x).foo(2); // typeof(this) = X
d.foo(3); // typeof(this) = D&
} Something like that, perhaps? |
The above would just allow Update to answer my own question: Yes, |
This (no pun intended) sounds promising! One thing I'm wondering about is a function that returns template <class Self>
constexpr auto&& value(this Self&& self) {
if (self.has_value()) {
return std::forward<Self>(self).m_value;
}
throw bad_optional_access(); // Ignore this part
} I think this function signature would work for constexpr and returning value: (forward this) -> forward _ == { ... } But how would we write the equivalent for this line? return std::forward<Self>(self).m_value; Would it be the following? return this.m_value; |
Yes. template <typename F>
auto not_fn(F&& f) {
return [f=forward<F>(f)](this auto&& self, auto&&.. args)
BOOST_HOF_RETURNS(
!invoke(
forward_like<decltype(self)>(f),
forward<decltype(args)>(args)...))
;
}
The
This is very similar to #572 (comment). |
I've always wanted this. A quirk with a deducing |
Deducing template <class charT, class traits = char_traits<charT>>
class basic_string_view {
private:
const_pointer data_;
size_type size_;
public:
constexpr const_iterator begin(this basic_string_view self) {
return self.data_;
}
constexpr const_iterator end(this basic_string_view self) {
return self.data_ + self.size_;
}
constexpr size_t size(this basic_string_view self) {
return self.size_;
}
constexpr const_reference operator[](this basic_string_view self, size_type pos) {
return self.data_[pos];
}
}; We could also allow a |
Let's be more clear. #572 (comment) says that the current
Today's For P0847 (deducing Now, where both of these features would meet is in If I'm analyzing this right, these features are not actually in conflict. |
Actually, But both
Additionally, from P2481:
What we already have from P2481 (as Cpp2 features):
Combining these two features, we get:
|
Requiring `=` has been a widely-requested change, and I think it does make the code clearer to read. See the Cpp2 code changes in this commit for examples. For example, `f: () expr;` must now be written as `f: () = expr;` For a function whose body is a single expression, the default return type (i.e., if not specified) is now `-> forward _`, which is Cpp1 `-> decltype(auto)` (which, importantly, can deduce a value). With this change, single-expression function bodies without `{ }` are still legal for any function, but as of this commit we have a clearer distinction in their use (which is reflected in the updates to the regression tests and other Cpp2 code in this commit): - It further encourages single-expression function bodies without `{ }` for unnamed function expressions (lambdas), by making more of those cases Do the Right Thing that the programmer intended. - It naturally discourages their overuse for named functions, because it will more often cause a compiler warning or error: - a warning that callers are not using a returned results, when the function is called without using its value - an error that a deduced return type makes the function order-dependent, when the function is called from earlier in the source file... this is because a deduced return types creates a dependency on the body, and it is inherent (not an artifact of either Cpp1 or Cpp2) But for those who liked that style, fear not, usually the answer is to just put the two characters `{ }` around the body... see examples in this commit, which I have to admit most are probably more readable even though I'm one of the ones who liked omitting the braces. Note: I realize that further evolution may not allow the `{ }`-free style for named functions. That may well be a reasonable further outcome. I think both of these are positive improvements.
For the same motivations as in P0847, I'd like to be able to write the equivalent of the "deducing this" feature in Cpp2.
Here's one example where the feature would prevent duplicating code:
Instead I'd like to write the
get
function once, with some kind of equivalent "deducing this" syntax that takes care of thethis
parameter and also the return type, e.g. along the lines of:The lowered C++ could duplicate the functions if it's targeting C++20, since the C++23 "deducing this" syntax won't be available.
If, in the future, cppfront supports some kind of
cpp_standard
flag (like proposed in #942) then the lowered code for C++23 could use the real "deducing this" feature.Will your feature suggestion eliminate X% of security vulnerabilities of a given kind in current C++ code?
No
Will your feature suggestion automate or eliminate X% of current C++ guidance literature?
Yes, in the same way that "deducing this" does for C++.
The text was updated successfully, but these errors were encountered: