Discussion:
Is inheritability of lambdas guaranteed by the standard?
(too old to reply)
Vincent Reverdy
2018-04-07 09:04:08 UTC
Permalink
Hello!

Does the current standard guarantee that one can inherit from lambdas?
There seems to be some debate about it:
https://stackoverflow.com/q/49704835/882932

Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Brian Bi
2018-04-07 09:46:50 UTC
Permalink
This is just my opinion:

- cpplearner's answer is not convincing. I find it hard to believe that
finality is intended to appertain only to the definition of a class and not
to the class type itself, particularly since `final` was originally an
attribute.
- Vincent's answer is a bit more convincing, but notes are not
normative, and it's not clear that it was intended for this to apply to
lambdas; it reads as though it's a simple consequence of the grammar, and
would thus apply to user-declared classes, but not necessarily to lambdas.
The "[...] provided this does not alter the observable behavior of the
program other than by changing [...]" bit: making the closure type final
would alter the observable behaviour. The thing I'm not entirely sure about
is whether unspecified aspects in there and the following paragraphs are
meant to be covered by that.
My opinion is that if certain behaviour was not specified in the
paragraphs below then it's not possible to violate this paragraph by
altering the merely assumed behaviour (*i.e.,* that an implementation
would not make the closure type final)---so, yes, it's legal for the
implementation to make it final.

At any rate, I think this is unclear enough to be worth opening a core
issue about.
Hello!
Does the current standard guarantee that one can inherit from lambdas?
There seems to be some debate about it: https://stackoverflow.com/q/
49704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/a/isocpp.org/group/std-
discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Hodges
2018-04-07 14:22:03 UTC
Permalink
Inheriting from lambdas is already in the wild.

It's also in my code base.

See example in cppreference

http://en.cppreference.com/w/cpp/utility/variant/visit
Post by Brian Bi
- cpplearner's answer is not convincing. I find it hard to believe
that finality is intended to appertain only to the definition of a class
and not to the class type itself, particularly since `final` was originally
an attribute.
- Vincent's answer is a bit more convincing, but notes are not
normative, and it's not clear that it was intended for this to apply to
lambdas; it reads as though it's a simple consequence of the grammar, and
would thus apply to user-declared classes, but not necessarily to lambdas.
The "[...] provided this does not alter the observable behavior of
the program other than by changing [...]" bit: making the closure type
final would alter the observable behaviour. The thing I'm not entirely sure
about is whether unspecified aspects in there and the following paragraphs
are meant to be covered by that.
My opinion is that if certain behaviour was not specified in the
paragraphs below then it's not possible to violate this paragraph by
altering the merely assumed behaviour (*i.e.,* that an implementation
would not make the closure type final)---so, yes, it's legal for the
implementation to make it final.
At any rate, I think this is unclear enough to be worth opening a core
issue about.
Hello!
Does the current standard guarantee that one can inherit from lambdas?
https://stackoverflow.com/q/49704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Vincent Reverdy
2018-04-07 14:27:03 UTC
Permalink
I know it's out there. It's in my codebase too. It's just that I realized
that I am not 100% sure anymore that lambdas are required to be inheritable
by the standard.
Post by Richard Hodges
Inheriting from lambdas is already in the wild.
It's also in my code base.
See example in cppreference
http://en.cppreference.com/w/cpp/utility/variant/visit
Post by Brian Bi
- cpplearner's answer is not convincing. I find it hard to believe
that finality is intended to appertain only to the definition of a class
and not to the class type itself, particularly since `final` was originally
an attribute.
- Vincent's answer is a bit more convincing, but notes are not
normative, and it's not clear that it was intended for this to apply to
lambdas; it reads as though it's a simple consequence of the grammar, and
would thus apply to user-declared classes, but not necessarily to lambdas.
The "[...] provided this does not alter the observable behavior of
the program other than by changing [...]" bit: making the closure type
final would alter the observable behaviour. The thing I'm not entirely sure
about is whether unspecified aspects in there and the following paragraphs
are meant to be covered by that.
My opinion is that if certain behaviour was not specified in the
paragraphs below then it's not possible to violate this paragraph by
altering the merely assumed behaviour (*i.e.,* that an implementation
would not make the closure type final)---so, yes, it's legal for the
implementation to make it final.
At any rate, I think this is unclear enough to be worth opening a core
issue about.
Hello!
Does the current standard guarantee that one can inherit from lambdas?
https://stackoverflow.com/q/49704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send
.
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Hodges
2018-04-07 14:31:48 UTC
Permalink
Post by Vincent Reverdy
I know it's out there. It's in my codebase too. It's just that I realized
that I am not 100% sure anymore that lambdas are required to be inheritable
by the standard.
Without it, any non-trivial use of std::visit becomes a ghastly mess. So I
would say, given the chance, we should force the issue.
Post by Vincent Reverdy
Post by Richard Hodges
Inheriting from lambdas is already in the wild.
It's also in my code base.
See example in cppreference
http://en.cppreference.com/w/cpp/utility/variant/visit
Post by Brian Bi
- cpplearner's answer is not convincing. I find it hard to believe
that finality is intended to appertain only to the definition of a class
and not to the class type itself, particularly since `final` was originally
an attribute.
- Vincent's answer is a bit more convincing, but notes are not
normative, and it's not clear that it was intended for this to apply to
lambdas; it reads as though it's a simple consequence of the grammar, and
would thus apply to user-declared classes, but not necessarily to lambdas.
The "[...] provided this does not alter the observable behavior of
the program other than by changing [...]" bit: making the closure type
final would alter the observable behaviour. The thing I'm not entirely sure
about is whether unspecified aspects in there and the following paragraphs
are meant to be covered by that.
My opinion is that if certain behaviour was not specified in the
paragraphs below then it's not possible to violate this paragraph by
altering the merely assumed behaviour (*i.e.,* that an
implementation would not make the closure type final)---so, yes, it's legal
for the implementation to make it final.
At any rate, I think this is unclear enough to be worth opening a core
issue about.
Hello!
Does the current standard guarantee that one can inherit from lambdas?
There seems to be some debate about it: https://stackoverflow.com/q/49
704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send
Visit this group at https://groups.google.com/a/is
ocpp.org/group/std-discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send
Visit this group at https://groups.google.com/a/is
ocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/a/isocpp.org/group/std-
discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Brian Bi
2018-04-08 04:04:34 UTC
Permalink
I agree with Richard. The standard should be reworded to make it clear that
inheriting from lambdas is permitted, and furthermore that the derived
class is actually instantiable. The standard should explicitly state that
the closure type is non-final and has no virtual base classes (no base
classes at all, perhaps).
Post by Richard Hodges
Post by Vincent Reverdy
I know it's out there. It's in my codebase too. It's just that I realized
that I am not 100% sure anymore that lambdas are required to be inheritable
by the standard.
Without it, any non-trivial use of std::visit becomes a ghastly mess. So I
would say, given the chance, we should force the issue.
Post by Vincent Reverdy
Post by Richard Hodges
Inheriting from lambdas is already in the wild.
It's also in my code base.
See example in cppreference
http://en.cppreference.com/w/cpp/utility/variant/visit
Post by Brian Bi
- cpplearner's answer is not convincing. I find it hard to believe
that finality is intended to appertain only to the definition of a class
and not to the class type itself, particularly since `final` was originally
an attribute.
- Vincent's answer is a bit more convincing, but notes are not
normative, and it's not clear that it was intended for this to apply to
lambdas; it reads as though it's a simple consequence of the grammar, and
would thus apply to user-declared classes, but not necessarily to lambdas.
The "[...] provided this does not alter the observable behavior of
the program other than by changing [...]" bit: making the closure type
final would alter the observable behaviour. The thing I'm not entirely sure
about is whether unspecified aspects in there and the following paragraphs
are meant to be covered by that.
My opinion is that if certain behaviour was not specified in the
paragraphs below then it's not possible to violate this paragraph by
altering the merely assumed behaviour (*i.e.,* that an
implementation would not make the closure type final)---so, yes, it's legal
for the implementation to make it final.
At any rate, I think this is unclear enough to be worth opening a core
issue about.
Hello!
Does the current standard guarantee that one can inherit from lambdas?
There seems to be some debate about it: https://stackoverflow.com/q/49
704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send
Visit this group at https://groups.google.com/a/is
ocpp.org/group/std-discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send
Visit this group at https://groups.google.com/a/is
ocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/a/is
ocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/a/isocpp.org/group/std-
discussion/.
--
*Brian Bi*
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicol Bolas
2018-04-08 06:35:20 UTC
Permalink
Post by Brian Bi
I agree with Richard. The standard should be reworded to make it clear
that inheriting from lambdas is permitted, and furthermore that the derived
class is actually instantiable. The standard should explicitly state that
the closure type is non-final and has no virtual base classes (no base
classes at all, perhaps).
My problem with spelling that out explicitly is... what *else* needs to be
spelled out explicitly? The way the wording stands now, it seems sufficient
to say that implementations aren't allowed to change observable behavior
relative to what is stated about the closure type. The standard doesn't say
the closure is `final`. Therefore, as far as I'm concerned, implementations
can't make them be `final`, since that would be a change in "observable
behavior".

Spelling things out in terms of `final` and so forth simply opens up a can
of worms; we'd have to go through every property and say whether or not it
should be allowed. And every time we add a new type property to the
language, we'd have to adjust the wording accordingly.

If the wording does need to be changed, then it needs to be changed in such
a way that it covers *everything* that we could reasonably want.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicolas Lesser
2018-04-08 06:54:58 UTC
Permalink
Post by Nicol Bolas
Post by Brian Bi
I agree with Richard. The standard should be reworded to make it clear
that inheriting from lambdas is permitted, and furthermore that the derived
class is actually instantiable. The standard should explicitly state that
the closure type is non-final and has no virtual base classes (no base
classes at all, perhaps).
My problem with spelling that out explicitly is... what *else* needs to
be spelled out explicitly? The way the wording stands now, it seems
sufficient to say that implementations aren't allowed to change observable
behavior relative to what is stated about the closure type. The standard
doesn't say the closure is `final`. Therefore, as far as I'm concerned,
implementations can't make them be `final`, since that would be a change in
"observable behavior".
I don't think so. Yes, implementations aren't allowed to change the
observable behavior that is specified, but if it isn't specified, how can
you know what the behavior should be? You can argue with that argument both
ways, because there is no behavior specified.
Post by Nicol Bolas
Spelling things out in terms of `final` and so forth simply opens up a can
of worms; we'd have to go through every property and say whether or not it
should be allowed. And every time we add a new type property to the
language, we'd have to adjust the wording accordingly.
That is true, but at least the standard could be explicit and say something
along the lines of "It is implementation-defined if the closure type has
any other property" or something like that. I don't know whether it is
implied by omission, because that's what I'd think. But also, I don't think
it's a big problem, because the standard is a technical description of a
language, so it needs to be explicit and clearly define everything. It
can't just omit stuff, especially if it is unclear.
Post by Nicol Bolas
If the wording does need to be changed, then it needs to be changed in
such a way that it covers *everything* that we could reasonably want.
Post by Brian Bi
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/a/isocpp.org/group/std-
discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicol Bolas
2018-04-08 16:10:31 UTC
Permalink
Post by Nicolas Lesser
Post by Nicol Bolas
Post by Brian Bi
I agree with Richard. The standard should be reworded to make it clear
that inheriting from lambdas is permitted, and furthermore that the derived
class is actually instantiable. The standard should explicitly state that
the closure type is non-final and has no virtual base classes (no base
classes at all, perhaps).
My problem with spelling that out explicitly is... what *else* needs to
be spelled out explicitly? The way the wording stands now, it seems
sufficient to say that implementations aren't allowed to change observable
behavior relative to what is stated about the closure type. The standard
doesn't say the closure is `final`. Therefore, as far as I'm concerned,
implementations can't make them be `final`, since that would be a change in
"observable behavior".
I don't think so. Yes, implementations aren't allowed to change the
observable behavior that is specified, but if it isn't specified, how can
you know what the behavior should be? You can argue with that argument both
ways, because there is no behavior specified.
Post by Nicol Bolas
Spelling things out in terms of `final` and so forth simply opens up a
can of worms; we'd have to go through every property and say whether or not
it should be allowed. And every time we add a new type property to the
language, we'd have to adjust the wording accordingly.
That is true, but at least the standard could be explicit and say
something along the lines of "It is implementation-defined if the closure
type has any other property" or something like that. I don't know whether
it is implied by omission, because that's what I'd think. But also, I don't
think it's a big problem, because the standard is a technical description
of a language, so it needs to be explicit and clearly define everything. It
can't just omit stuff, especially if it is unclear.
But it isn't omitting anything. It's simply not explicitly listing every
single property with a checkbox beside it saying whether or not it's OK for
an implementation to alter it. There is simply a blanket statement about
the variability of implementations, which explicitly says that "observable
behavior" variances are not allowed except in specific cases.

Let's consider another example of such statements. There's nothing that
explicitly says `vector` implementations could not be declared `final`.
However, there is a listing of the `vector` template class, and `final`
isn't in that listing. Therefore, implementations aren't allowed to put it
there, because that would be "observable behavior" which is different from
that listing.

The standard doesn't have to explicitly say `vector` can't be `final`
because it already *implicitly* said so. The same goes with lambdas: the
standard does not say that the class is declared `final`, so adding `final`
would be a behavioral variance. Therefore, it can't be there.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicolas Lesser
2018-04-08 17:09:48 UTC
Permalink
Post by Nicol Bolas
But it isn't omitting anything. It's simply not explicitly listing every
single property with a checkbox beside it saying whether or not it's OK for
an implementation to alter it. There is simply a blanket statement about
the variability of implementations, which explicitly says that "observable
behavior" variances are not allowed except in specific cases.
Exactly, but it doesn't state what the observable behavior should be in the
case of final, so it's not clear what exactly would constitute a change in
observable behavior. I could argue that my implementation uses final on
closure types, and therefore, removing `final` would constitute a change in
observable behavior, and thus disallowed by the standard.

Let's consider another example of such statements. There's nothing that
Post by Nicol Bolas
explicitly says `vector` implementations could not be declared `final`.
Hmm but there is. [vector.overview]p2 describes how the vector class should
look like, and there it is not marked final, so yes, implementations can't
mark it final.
Post by Nicol Bolas
However, there is a listing of the `vector` template class, and `final`
isn't in that listing. Therefore, implementations aren't allowed to put it
there, because that would be "observable behavior" which is different from
that listing.
If you mean [vector.overview]p2, then yes you're right and I agree.
Post by Nicol Bolas
The standard doesn't have to explicitly say `vector` can't be `final`
because it already *implicitly* said so.
It is explicit through the vector synopsis in [vector.overview]p2.

The same goes with lambdas: the standard does not say that the class is
Post by Nicol Bolas
declared `final`, so adding `final` would be a behavioral variance.
Therefore, it can't be there.
Ok, so I'm going to say: the standard does not say that the class is not
declared `final`, so removing `final` would be a behavioral variance.
Therefore, it must be there.

Because the standard doesn't mention `final` at all, it is completely
unclear if it should be there or not. There is no "behavioral variance"
like you say without a basis/root, if you know what I mean. The standard
doesn't say anything what `std::is_final_v<decltype([](){})>` results in,
so the observable behavior is not even defined and it's unclear what the
trait is supposed to evaluate to. Also, that sentence about observable
behavior in closure types ([expr.prim.lambda.closure]p2) doesn't even apply
Post by Nicol Bolas
An implementation may define the closure type differently* from what is
described below* provided this does not alter the observable behavior of
the program other than by changing:

The "from what is described below" part is important. `final` isn't
discussed "below", so it's not clear what should happen.

But I don't know what the answer is to: What should happen when the
standard doesn't describe something? My guess is: It's unspecified behavior.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicol Bolas
2018-04-08 20:00:25 UTC
Permalink
Post by Nicolas Lesser
Post by Nicol Bolas
But it isn't omitting anything. It's simply not explicitly listing every
single property with a checkbox beside it saying whether or not it's OK for
an implementation to alter it. There is simply a blanket statement about
the variability of implementations, which explicitly says that "observable
behavior" variances are not allowed except in specific cases.
Exactly, but it doesn't state what the observable behavior should be in
the case of final, so it's not clear what exactly would constitute a change
in observable behavior. I could argue that my implementation uses final on
closure types, and therefore, removing `final` would constitute a change in
observable behavior, and thus disallowed by the standard.
Let's consider another example of such statements. There's nothing that
Post by Nicol Bolas
explicitly says `vector` implementations could not be declared `final`.
Hmm but there is. [vector.overview]p2 describes how the vector class
should look like, and there it is not marked final, so yes, implementations
can't mark it final.
Post by Nicol Bolas
However, there is a listing of the `vector` template class, and `final`
isn't in that listing. Therefore, implementations aren't allowed to put it
there, because that would be "observable behavior" which is different from
that listing.
If you mean [vector.overview]p2, then yes you're right and I agree.
Post by Nicol Bolas
The standard doesn't have to explicitly say `vector` can't be `final`
because it already *implicitly* said so.
It is explicit through the vector synopsis in [vector.overview]p2.
The same goes with lambdas: the standard does not say that the class is
Post by Nicol Bolas
declared `final`, so adding `final` would be a behavioral variance.
Therefore, it can't be there.
Ok, so I'm going to say: the standard does not say that the class is not
declared `final`, so removing `final` would be a behavioral variance.
Therefore, it must be there.
Because the standard doesn't mention `final` at all, it is completely
unclear if it should be there or not. There is no "behavioral variance"
like you say without a basis/root, if you know what I mean. The standard
doesn't say anything what `std::is_final_v<decltype([](){})>` results in,
so the observable behavior is not even defined and it's unclear what the
trait is supposed to evaluate to. Also, that sentence about observable
behavior in closure types ([expr.prim.lambda.closure]p2) doesn't even apply
Post by Nicol Bolas
An implementation may define the closure type differently* from what is
described below* provided this does not alter the observable behavior of
The "from what is described below" part is important. `final` isn't
discussed "below", so it's not clear what should happen.
There are only two states for the `final` property: present or absent.
There is no "indeterminate, maybe there maybe not" state for the property.
If it's there, then it's there; if it's not there, then it's *not there*.
And "below" does not say that it's there, and therefore it is *not there*.

This is why you can look at the `vector` template declaration and know that
it's not `final`. Because it doesn't say that it is `final`. And just like
`vector`, a closure type can't be `final`.

But I don't know what the answer is to: What should happen when the
Post by Nicolas Lesser
standard doesn't describe something? My guess is: It's unspecified behavior.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Tony V E
2018-04-09 02:58:33 UTC
Permalink
Post by Nicol Bolas
Post by Nicolas Lesser
Post by Nicol Bolas
But it isn't omitting anything. It's simply not explicitly listing every
single property with a checkbox beside it saying whether or not it's OK for
an implementation to alter it. There is simply a blanket statement about
the variability of implementations, which explicitly says that "observable
behavior" variances are not allowed except in specific cases.
Exactly, but it doesn't state what the observable behavior should be in
the case of final, so it's not clear what exactly would constitute a change
in observable behavior. I could argue that my implementation uses final on
closure types, and therefore, removing `final` would constitute a change in
observable behavior, and thus disallowed by the standard.
Let's consider another example of such statements. There's nothing that
Post by Nicol Bolas
explicitly says `vector` implementations could not be declared `final`.
Hmm but there is. [vector.overview]p2 describes how the vector class
should look like, and there it is not marked final, so yes, implementations
can't mark it final.
Post by Nicol Bolas
However, there is a listing of the `vector` template class, and `final`
isn't in that listing. Therefore, implementations aren't allowed to put it
there, because that would be "observable behavior" which is different from
that listing.
If you mean [vector.overview]p2, then yes you're right and I agree.
Post by Nicol Bolas
The standard doesn't have to explicitly say `vector` can't be `final`
because it already *implicitly* said so.
It is explicit through the vector synopsis in [vector.overview]p2.
The same goes with lambdas: the standard does not say that the class is
Post by Nicol Bolas
declared `final`, so adding `final` would be a behavioral variance.
Therefore, it can't be there.
Ok, so I'm going to say: the standard does not say that the class is not
declared `final`, so removing `final` would be a behavioral variance.
Therefore, it must be there.
Because the standard doesn't mention `final` at all, it is completely
unclear if it should be there or not. There is no "behavioral variance"
like you say without a basis/root, if you know what I mean. The standard
doesn't say anything what `std::is_final_v<decltype([](){})>` results
in, so the observable behavior is not even defined and it's unclear what
the trait is supposed to evaluate to. Also, that sentence about observable
behavior in closure types ([expr.prim.lambda.closure]p2) doesn't even apply
Post by Nicol Bolas
An implementation may define the closure type differently* from what
is described below* provided this does not alter the observable behavior
The "from what is described below" part is important. `final` isn't
discussed "below", so it's not clear what should happen.
There are only two states for the `final` property: present or absent.
There is no "indeterminate, maybe there maybe not" state for the property.
If it's there, then it's there; if it's not there, then it's *not there*.
And "below" does not say that it's there, and therefore it is *not there*.
Then why do we go through the trouble of specifying other parts, like "The
function call operator ... is neither virtual nor declared volatile".
Should we remove the mention of volatile and just assume it?
There are many more examples in that section.

Typically when things aren't specified, they are unspecified.
Post by Nicol Bolas
This is why you can look at the `vector` template declaration and know
that it's not `final`. Because it doesn't say that it is `final`. And just
like `vector`, a closure type can't be `final`.
vector is declared in code, where yes, it is black and white. Either final
or not. Lambdas are not declared in code.
Post by Nicol Bolas
But I don't know what the answer is to: What should happen when the
Post by Nicolas Lesser
standard doesn't describe something? My guess is: It's unspecified behavior.
--
--
Be seeing you,
Tony
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Vincent Reverdy
2018-04-09 04:06:20 UTC
Permalink
So given the fact that this discussion already has 12 posts... I guess we
can agree that the standard is not as clear as it should be. If it was
clear, the answer to my original message would have been "It is defined in
*some paragraph of the standard*, kthxbye". And it's definitely not the
case.

So my guess is that it's worth submitting a core issue, even if the answer
is "it's actually well defined for reasons A, B, and C".

So the next question (and because I never submitted a core issue) is how
should we reword the standard.

And maybe we need something stronger than final, because we can have both
final and non-final unions, and we cannot inherit from both of them:

#include <iostream>
#include <type_traits>

struct nonfinal_class {};
struct final_class final {};
union nonfinal_union {};
union final_union final {};

int main(int, char**) {
std::cout << std::is_final_v<nonfinal_class>;
std::cout << std::is_final_v<final_class>;
std::cout << std::is_final_v<nonfinal_union>;
std::cout << std::is_final_v<final_union>;
std::cout << std::endl;
return 0;
}

// Prints 0101

So I guess we need a wording that states that we can inherit from lambdas,
and that the derived class will be instantiable.

Suggestions are very welcome.

Vincent
Post by Vincent Reverdy
Hello!
Does the current standard guarantee that one can inherit from lambdas?
https://stackoverflow.com/q/49704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Nicolas Lesser
2018-04-09 04:55:03 UTC
Permalink
Post by Vincent Reverdy
So given the fact that this discussion already has 12 posts... I guess we
can agree that the standard is not as clear as it should be. If it was
clear, the answer to my original message would have been "It is defined in
*some paragraph of the standard*, kthxbye". And it's definitely not the
case.
So my guess is that it's worth submitting a core issue, even if the answer
is "it's actually well defined for reasons A, B, and C".
So the next question (and because I never submitted a core issue) is how
should we reword the standard.
And maybe we need something stronger than final, because we can have both
Why are you mentioning unions? Lambdas can't be unions, so I'm not sure
what your point is.
Post by Vincent Reverdy
#include <iostream>
#include <type_traits>
struct nonfinal_class {};
struct final_class final {};
union nonfinal_union {};
union final_union final {};
int main(int, char**) {
std::cout << std::is_final_v<nonfinal_class>;
std::cout << std::is_final_v<final_class>;
std::cout << std::is_final_v<nonfinal_union>;
std::cout << std::is_final_v<final_union>;
std::cout << std::endl;
return 0;
}
// Prints 0101
So I guess we need a wording that states that we can inherit from lambdas,
and that the derived class will be instantiable.
Saying that the closure type is not final should be enough.

Still, it might be better to try to future-proof the closure type, because
who knows what property we will add to classes. I think it would be cleaner
and more descriptive if the closure type is written in code along with some
description of various stuff that depends on the lambda (constexpr, const,
template parameters, ...).
Post by Vincent Reverdy
Suggestions are very welcome.
Vincent
Post by Vincent Reverdy
Hello!
Does the current standard guarantee that one can inherit from lambdas?
https://stackoverflow.com/q/49704835/882932
Thank you,
Vincent
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Tony V E
2018-04-09 04:59:28 UTC
Permalink
<html><head></head><body lang="en-US" style="background-color: rgb(255, 255, 255); line-height: initial;"> <div style="width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">When submitting a core issue, you don't really need wording. It can help, but unless you speak standardese, they are just going to reword it anyhow.</div> <div style="width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);"><br style="display:initial"></div> <div style="font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">Sent&nbsp;from&nbsp;my&nbsp;BlackBerry&nbsp;portable&nbsp;Babbage&nbsp;Device</div> <table width="100%" style="background-color:white;border-spacing:0px;"> <tbody><tr><td colspan="2" style="font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);"> <div style="border-style: solid none none; border-top-color: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0in; font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;"> <div><b>From: </b>Vincent Reverdy</div><div><b>Sent: </b>Monday, April 9, 2018 12:06 AM</div><div><b>To: </b>ISO C++ Standard - Discussion</div><div><b>Reply To: </b>std-***@isocpp.org</div><div><b>Subject: </b>[std-discussion] Re: Is inheritability of lambdas guaranteed by the standard?</div></div></td></tr></tbody></table><div style="border-style: solid none none; border-top-color: rgb(186, 188, 209); border-top-width: 1pt; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);"></div><br><div id="_originalContent" style=""><div dir="ltr"><div>So given the fact that this discussion already has 12 posts... I guess we can agree that the standard is not as clear as it should be. If it was clear, the answer to my original message would have been "It is defined in *some paragraph of the standard*, kthxbye". And it's definitely not the case.</div><div><br></div><div>So my guess is that it's worth submitting a core issue, even if the answer is "it's actually well defined for reasons A, B, and C".</div><div><br></div><div>So the next question (and because I never submitted a core issue) is how should we reword the standard.<br></div><div><br></div><div>And maybe we need something stronger than final, because we can have both final and non-final unions, and we cannot inherit from both of them:</div><div><br></div><div><div style="background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;" class="prettyprint"><code class="prettyprint"><div class="subprettyprint"><span style="color: #800;" class="styled-by-prettify">#include</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #080;" class="styled-by-prettify">&lt;iostream&gt;</span><span style="color: #000;" class="styled-by-prettify"><br></span><span style="color: #800;" class="styled-by-prettify">#include</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #080;" class="styled-by-prettify">&lt;type_traits&gt;</span><span style="color: #000;" class="styled-by-prettify"><br><br></span><span style="color: #008;" class="styled-by-prettify">struct</span><span style="color: #000;" class="styled-by-prettify"> nonfinal_class </span><span style="color: #660;" class="styled-by-prettify">{};</span><span style="color: #000;" class="styled-by-prettify"><br></span><span style="color: #008;" class="styled-by-prettify">struct</span><span style="color: #000;" class="styled-by-prettify"> final_class </span><span style="color: #008;" class="styled-by-prettify">final</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #660;" class="styled-by-prettify">{};</span><span style="color: #000;" class="styled-by-prettify"><br></span><span style="color: #008;" class="styled-by-prettify">union</span><span style="color: #000;" class="styled-by-prettify"> nonfinal_union </span><span style="color: #660;" class="styled-by-prettify">{};</span><span style="color: #000;" class="styled-by-prettify"><br></span><span style="color: #008;" class="styled-by-prettify">union</span><span style="color: #000;" class="styled-by-prettify"> final_union </span><span style="color: #008;" class="styled-by-prettify">final</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #660;" class="styled-by-prettify">{};</span><span style="color: #000;" class="styled-by-prettify"><br><br></span><span style="color: #008;" class="styled-by-prettify">int</span><span style="color: #000;" class="styled-by-prettify"> main</span><span style="color: #660;" class="styled-by-prettify">(</span><span style="color: #008;" class="styled-by-prettify">int</span><span style="color: #660;" class="styled-by-prettify">,</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #008;" class="styled-by-prettify">char</span><span style="color: #660;" class="styled-by-prettify">**)</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #660;" class="styled-by-prettify">{</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">cout </span><span style="color: #660;" class="styled-by-prettify">&lt;&lt;</span><span style="color: #000;" class="styled-by-prettify"> std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">is_final_v</span><span style="color: #080;" class="styled-by-prettify">&lt;nonfinal_class&gt;</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">cout </span><span style="color: #660;" class="styled-by-prettify">&lt;&lt;</span><span style="color: #000;" class="styled-by-prettify"> std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">is_final_v</span><span style="color: #080;" class="styled-by-prettify">&lt;final_class&gt;</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">cout </span><span style="color: #660;" class="styled-by-prettify">&lt;&lt;</span><span style="color: #000;" class="styled-by-prettify"> std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">is_final_v</span><span style="color: #080;" class="styled-by-prettify">&lt;nonfinal_union&gt;</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">cout </span><span style="color: #660;" class="styled-by-prettify">&lt;&lt;</span><span style="color: #000;" class="styled-by-prettify"> std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">is_final_v</span><span style="color: #080;" class="styled-by-prettify">&lt;final_union&gt;</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">cout </span><span style="color: #660;" class="styled-by-prettify">&lt;&lt;</span><span style="color: #000;" class="styled-by-prettify"> std</span><span style="color: #660;" class="styled-by-prettify">::</span><span style="color: #000;" class="styled-by-prettify">endl</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br>&nbsp; &nbsp; </span><span style="color: #008;" class="styled-by-prettify">return</span><span style="color: #000;" class="styled-by-prettify"> </span><span style="color: #066;" class="styled-by-prettify">0</span><span style="color: #660;" class="styled-by-prettify">;</span><span style="color: #000;" class="styled-by-prettify"><br></span><span style="color: #660;" class="styled-by-prettify">}</span><span style="color: #000;" class="styled-by-prettify"><br><br></span><span style="color: #800;" class="styled-by-prettify">// Prints 0101</span><span style="color: #000;" class="styled-by-prettify"><br></span></div></code></div><br>So I guess we need a wording that states that we can inherit from lambdas, and that the derived class will be instantiable.</div><div><br></div><div>Suggestions are very welcome.</div><div><br></div><div>Vincent<br></div><div><br></div><div><br></div><br>Le samedi 7 avril 2018 04:04:08 UTC-5, Vincent Reverdy a écrit&nbsp;:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir="ltr"><div>Hello!</div><div><br></div><div>Does the current standard guarantee that one can inherit from lambdas?</div><div>There seems to be some debate about it: <a href="https://stackoverflow.com/q/49704835/882932" target="_blank" rel="nofollow" onmousedown="this.href='https://www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fq%2F49704835%2F882932\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHyB4lOUHXFATcW_1o1enKOV9Rb7g';return true;" onclick="this.href='https://www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fq%2F49704835%2F882932\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHyB4lOUHXFATcW_1o1enKOV9Rb7g';return true;">https://stackoverflow.com/q/<wbr>49704835/882932</a></div><div><br></div><div>Thank you,</div><div>Vincent<br></div></div></blockquote></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-discussion+***@isocpp.org">std-discussion+***@isocpp.org</a>.<br>
To post to this group, send email to <a href="mailto:std-***@isocpp.org">std-***@isocpp.org</a>.<br>
Visit this group at <a href="https://groups.google.com/a/isocpp.org/group/std-discussion/">https://groups.google.com/a/isocpp.org/group/std-discussion/</a>.<br>
<br><!--end of _originalContent --></div></body></html>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Discussion&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-discussion+***@isocpp.org">std-discussion+***@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-***@isocpp.org">std-***@isocpp.org</a>.<br />
Visit this group at <a href="https://groups.google.com/a/isocpp.org/group/std-discussion/">https://groups.google.com/a/isocpp.org/group/std-discussion/</a>.<br />
Nevin Liber
2018-04-09 04:58:56 UTC
Permalink
Post by Vincent Reverdy
So my guess is that it's worth submitting a core issue, even if the answer
is "it's actually well defined for reasons A, B, and C".
I think it is, although the answer you get back may be to write a (small)
EWG paper. I don't believe this particular issue has been discussed.
Post by Vincent Reverdy
So the next question (and because I never submitted a core issue) is how
should we reword the standard.
Leave that up to CWG?
Post by Vincent Reverdy
And maybe we need something stronger than final, because we can have both
I'm not sure what this means. There are plenty of things you can't
necessarily derive from; for instance, anything with a virtual final
destructor.

If you are looking for some sort of is_derivable trait, I can tell you it
is a can of worms... :-)
Post by Vincent Reverdy
So I guess we need a wording that states that we can inherit from lambdas,
and that the derived class will be instantiable.
What do you mean by "will be instantiable" that isn't already covered by
the rules for what constructors/assignment operators a given lambda has?

If you wish to expand this, IMO it'll take a not-so-small EWG paper to do
it.
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> +1-847-691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...