Date: Mon, 4 Nov 2019 18:57:42 +0000
>
>
> Move Semantics. Compile Time evaluation. Concepts (which make life
> absurdly easier for people that have to otherwise SFINAE stuff). Class-Type
> Template parameters. std::launder. Examples of stuff we couldn’t do until
> the language introduced them.
>
Move semantics is probably within that one percent that was impossible to
achieve (to some extent it is a replacement for swap()). Compile time
evaluation has been possible with "enum { value = sizeof(...) ==
sizeof(true_type) ? 4 : 6" and so on..., Concepts are sfinae/enable_if,
class type template parameters - just make them flat.
But I suppose this discussion has little to do with the proposal :)
> The issue is not that it can be done already. Its that to make use of this
> proposal, you aren’t saving a lot of time or effort over what is already
> being done. There is also a lot more control that can be had over manually
> doing this with using declarations.
>
Well, I am starting to understand you less and less. All language
constructions and invariants that are kept and enforced by a language, are
not about having ultimate control. They are rather about opposite - about
making common things easy, about handing some things over to a compiler. If
we want control we should eradicate C and C++ and start programming in
assembler - what if optimiser in a compiler will do your its job poorly,
after all, how can you trust it, where is our control?
About time: "you aren’t saving a lot of time or effort over what is already
being done".
What do you mean by "a lot of time"? If it saves 0.01% I think it is a huge
win. Just multiply it by the amount of time of all developers.
Moreover, as I have already said, time is not the only thing to consider.
Another thing to consider is whether the proposal allows to express your
intent more clearly.
Namely, for class non-type template parameters, whether it copies or just
> references.
>
Sure, but do you think there is a point in having a copy of const lvalue?
> Additional point, what about partial specializations. What about full
> specializations. How does the proposal deal with specializations? Are the
> old, unspecialized names visible, or are only the names of the
> specializations template parameters visible? What if the specialization
> wants to suppress one or more of the names.
>
Those are indeed good questions.
First of all, there are
- opt-in approach: a (partial) specialisation is to explicitly say that
it wants to propagate it's template arguments (as primary template does)
- and opt-out approach: a (partial) specialisation is to explicitly say
that it wants to suppress propagation.
The opt-in approach could look like:
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<*public *T*> {
public:
// value_type is implicitly generated
// using value_type = T*;
// without public above, it would not
};
The opt-out approach also looks reasonable, imagine, for example
vector<bool> - this partial specialisation wants to declare value_type =
bool, exactly as in the primary template.
Now, if we chose this opt-out approach, there are a couple of ways of how
(partial) specialisations can supress/changed propagated template
parameters:
- Allow declaration of the same name without generating error (or revert
the plan to generate errors on name clashes altogether).
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<T*> {
public:
// Can be redeclared with the same name
using value_type = T;
};
- Use delete keyword
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<T* = delete> {
// there is no value_type
};
The advantage of this option, is that it might be possible to remove the
using/typedef completely.
>
>
> Move Semantics. Compile Time evaluation. Concepts (which make life
> absurdly easier for people that have to otherwise SFINAE stuff). Class-Type
> Template parameters. std::launder. Examples of stuff we couldn’t do until
> the language introduced them.
>
Move semantics is probably within that one percent that was impossible to
achieve (to some extent it is a replacement for swap()). Compile time
evaluation has been possible with "enum { value = sizeof(...) ==
sizeof(true_type) ? 4 : 6" and so on..., Concepts are sfinae/enable_if,
class type template parameters - just make them flat.
But I suppose this discussion has little to do with the proposal :)
> The issue is not that it can be done already. Its that to make use of this
> proposal, you aren’t saving a lot of time or effort over what is already
> being done. There is also a lot more control that can be had over manually
> doing this with using declarations.
>
Well, I am starting to understand you less and less. All language
constructions and invariants that are kept and enforced by a language, are
not about having ultimate control. They are rather about opposite - about
making common things easy, about handing some things over to a compiler. If
we want control we should eradicate C and C++ and start programming in
assembler - what if optimiser in a compiler will do your its job poorly,
after all, how can you trust it, where is our control?
About time: "you aren’t saving a lot of time or effort over what is already
being done".
What do you mean by "a lot of time"? If it saves 0.01% I think it is a huge
win. Just multiply it by the amount of time of all developers.
Moreover, as I have already said, time is not the only thing to consider.
Another thing to consider is whether the proposal allows to express your
intent more clearly.
Namely, for class non-type template parameters, whether it copies or just
> references.
>
Sure, but do you think there is a point in having a copy of const lvalue?
> Additional point, what about partial specializations. What about full
> specializations. How does the proposal deal with specializations? Are the
> old, unspecialized names visible, or are only the names of the
> specializations template parameters visible? What if the specialization
> wants to suppress one or more of the names.
>
Those are indeed good questions.
First of all, there are
- opt-in approach: a (partial) specialisation is to explicitly say that
it wants to propagate it's template arguments (as primary template does)
- and opt-out approach: a (partial) specialisation is to explicitly say
that it wants to suppress propagation.
The opt-in approach could look like:
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<*public *T*> {
public:
// value_type is implicitly generated
// using value_type = T*;
// without public above, it would not
};
The opt-out approach also looks reasonable, imagine, for example
vector<bool> - this partial specialisation wants to declare value_type =
bool, exactly as in the primary template.
Now, if we chose this opt-out approach, there are a couple of ways of how
(partial) specialisations can supress/changed propagated template
parameters:
- Allow declaration of the same name without generating error (or revert
the plan to generate errors on name clashes altogether).
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<T*> {
public:
// Can be redeclared with the same name
using value_type = T;
};
- Use delete keyword
template <public class value_type>
class Foo {
// value_type is implicitly generated
};
template <class T>
class Foo<T* = delete> {
// there is no value_type
};
The advantage of this option, is that it might be possible to remove the
using/typedef completely.
>
Received on 2019-11-04 13:00:27