const auto &i = expr;
template <class U> void f(const U& u);
std::unique_ptr<auto> p = foo();
template <class U> void f(std::unique_ptr<U> u);
auto l = [] (std::unique_ptr<auto> p) { ... };
void foo(std::vector<auto> const& v) { ... }
pair<auto, auto> x = foo();
static_assert(decltype(x.first) != decltype(x.second), "Error");
static_assert(!std::is_same<decltype(x.first), decltype(x.second)>(), "Error");
To do that, you should expand 'auto' semantics to allow parameter type identifiers to be explicitly specified, instead of being implicit (plain auto). Which just leads you to using template parameters as an already existing syntax. Also remember that identifiers declared with 'auto' refer to values. So you can't do what Ville said without messing auto, seriously.
You are then unable to provide a match for your proposed std::pair<auto,auto> in a function type signature, function template overload, class template partial specialization for where different types are required, without making this a 'catch-all' pattern in a deducible context of a template parameter list. Therefore, because of this implicit assumption, you are continuously forced to use sfinae (and expand the rules for it) every time you'd use such syntax.
Consider also interaction with concepts and variadics. Not a pretty or unambiguous sight.
George,
I'm not sure what your point is. Why doesn't the static_assert() solve Ville's puzzle? Why is it necessary to refer to parameter type identifiers explicitly? Also, what do you mean by "identifiers declared with 'auto' refers to values"?
template<typename A, typename B> std::enable_if_t<!std::is_same<A,B>::value, void> function(std::pair<A,B>) {} template<typename T> void fun(std::pair<T,T>) {} template<typename A, typename B> void fun (std::pair<A,B>) {}
void function(std::pair<auto,auto> x) {}
void function(std::pair<auto A,auto B> x) {}
decltype(auto) function(std::pair<auto A,auto B> x) { return x.first; }
auto l = [] (auto a, auto b) { };
In fact, I did mention in my previous email that you can be inspired by generic C++14 lambdas for this; but such constructs by far, are not covering the issues arising when all kinds of parameters are involved, aka non-type, type, template-type as well as partial ordering matching. Not to mention the combination with variadics.
In essence, such proposed of auto for completely substituting the concept of a template parameter list, is problematic for doing any sort of bounded polymorphism (one of these cases is Ville's problem), while for that purpose concepts could be combined to offer a better solution.
But then again, concepts are tied to template parameter and argument lists. Which means that in this context, that way of handling parametric polymorphism in c++ with ’auto’ everywhere needs to be magically shoehorned into concepts (somehow) so that you can avoid seeing 'template'.
Of course, you could make a proposal for turning 'auto'-ness into something that works like Hindley–Milner type inference for C++, getting rid of every kind of type "cue", but that is neither the direction c++ is going towards right now nor would it be a small change otherwise.
For the record, the incompleteness of 'auto' in C++11 led to problems with expression templates. Automatic type inference within the rules that we have can be very, very tricky to expand without breaking code using such rules.
Again, just some thoughts; in conclusion, such use of 'auto' can be problematic unless it is very constrained by context to serve a shorthand for type parameters over cases where bounded polymorphism is not actually required. Generic C++14 lambdas were such a case, but they do not have the complexities of template parameter and argument lists.
Regards,
George
In your formulation, the type is in the end the same in both the first and the second type in std::pair, T, therefore it does not give you a guarantee that these two are different unless you use additional syntax for constraining the second.
In your example there is no such constraint or implication of it; and even if placed there, it still does not have a real notational advantage over regular templates. Not an easy path when you already have partial ordering and overloads doing the job for you in this particular case. What if more than two are involved?
Also proves that additional syntax is required to disambiguate for uses of auto within parameter lists for being a typename substitute or even a template-type parameter one.
Regards,
George
Under this assumption, as stated in previous emails, you would still have no way to explicitly specify (or sfinae) an instantiated class template type related to T given that no T identifier exists yet. See auto -> decltype syntax; decltype(auto) is also unconstrained as to T. So it is a very limiting shorthand respect to the canonical way of doing things.
It is not just variable declarations though that suffer.
Of course, we already analyzed this solution, but do show how we can use std::pair<auto,auto> in an argument list for specifying the two types must be different:
void fun(std::pair<auto, auto>) {}
Without resorting to multiple sfinae hacks like Andy is proposing; newer constructs should not lead to more complex code over the canonical solution with templates and partial ordering.
Also, return type sfinae manipulation is impaired to having to use auto -> decltype(...) constructs. In essence, verbosity.
As you said, it will be done in due course I guess. Perhaps Andy should consider this case though.
In essence then, we are in agreement; you do not gain any notational advantage for when types are different with the proposed 'auto' syntax extension. I am saying that the canonical way already covers all corners. Nothing more.
Again, this has already been discussed. See previous emails on this thread on why you would have problems with that as it is. You do not even gain total equivalence over canonical template syntax, if that is your goal.
Never implied that it wasn't in. But any variation requiring bounded polymorphism (one case is caring about different types) fails to do so without resorting to SFINAE once that use of auto kicks in. And even then, trivial return type constraints become impossible without complex SFINAE since the identifiers ate declared in the argument list.
It is interesting to note that Sutton said that should any kind of template meta-programming be necessary for doing what concepts are doing, it would make concepts a failed experiment. I would not be so harsh, but in that use of 'auto' you just end up using tricks like Andy.
In essence, you cannot avoid using a template parameter list through such auto use unless all is unboundedly polymorphic, and concepts with auto are definitely not Hindley-Milner.
Which is what has already been said, but you ignored it. The notation gets longer and weirder with such placeholders, not offering any real no rational advantage. You are only exchanging 'typename' with auto plus decltype for constraining even in the most trivial case.
I agree that this is not what concepts are designed for, I am only saying that people like Andy are demonstrating a trend in expanding the semantics of type inference that is problematic over already existing practice.
As for the concepts group, whose public work I am aware of, I do not believe that they would consider all outsider opinions on this matter, even if they are right. Anything not taking place in public is not worth it.
If you do not care about constraints yes, but Andy's decltype use should warn of something.
It gets weirder when you have to use decltype tricks like Andy did. Therefore, such use of auto is very restrictive for only some cases of unbound polymorphism; it does not offer a viable substitution for template parameter lists in the general case. See previous posts on this. It fitted C++14 genetic lambdas because of the constraints lambdas have themselves.
I am not saying it is totally useless, I am saying that it much, much, much less useful once decltype tricks have to enter the scene. Imagine having to read code using such overloads submitting to partial ordering.
In essence, it encourages metaprogrammimg boilerplate where there isn't need for.
At any rate, what the original message asks for is already part of the Concepts TS proposal.
void foo(auto x) { }
void foo(std::vector<auto> x);
On 2 October 2014 13:11, Andy Prowl <andy....@gmail.com> wrote:
>> At any rate, what the original message asks for is already part of the
>> Concepts TS proposal.
> That would be good news, but are you sure this is the case? Looking at
Based on a very new working draft that is not yet published, yes, I am sure.
I took the example I pasted from that draft.
> Same thing for variable declarations. Now I hope you will prove me wrong, so
> we can close this thread :)
I think we should close this thread. :)
George,
I'm not sure about what trend "people like me" are demonstrating, but honestly I have troubles understanding most of the concerns you are expressing. In particular, it seems to me that they are pretty much orthogonal to my proposal.
For example, already today there are situations where using trailing return type syntax is necessary, depending on what we want to do. And even with regular template syntax, you won't be able to avoid SFINAE for e.g. expressing the fact that two template type arguments must be different.
#include <cstdio> #include <utility> template<typename A, typename B> void function(std::pair<A,B>) { printf("different\n"); } template<typename A> void function(std::pair<A,A>) { printf("same\n"); } int main() { function(std::pair<int,long>()); function(std::pair<int,int>()); return 0; }
template<typename A, typename B> std::enable_if_t<!std::is_same<A,B>::value,void> function(std::pair<A,B>) { printf("different\n"); }
template<typename A, typename B> void function(std::pair<A,B>) { static_assert(!std::is_same<A,B>::value, "they cannot be the same!"); printf("different\n"); }
void function(std::pair<auto{A}, auto{B}>) { static_assert(!std::is_same<A,B>::value, "they cannot be the same!"); printf("different\n"); }
Regarding your concerns on the original example of std::pair<auto, auto>, my proposal doesn't really change anything: if you wanted to express the constraint that the types must be different *today*, you would still have to resort to static assertions and decltype, so I believe what I'm after doesn't make the situation worse.
I consider the thread closed, but given that Andy tries to make a point, I will just show the flaws in that reasoning for posterity.
On 10/02/2014 01:17 PM, Andy Prowl wrote:
George,
I'm not sure about what trend "people like me" are demonstrating, but honestly I have troubles understanding most of the concerns you are expressing. In particular, it seems to me that they are pretty much orthogonal to my proposal.
Andy,
The double quoted extract in context is implicitly refering to people who enjoy automatic type inference and is not intended as a discrediting subterfuge, which is quite usual by some members of this list. I consider myself part of the people who enjoy automatic type inference, to some limited extent.
For example, already today there are situations where using trailing return type syntax is necessary, depending on what we want to do. And even with regular template syntax, you won't be able to avoid SFINAE for e.g. expressing the fact that two template type arguments must be different.
Incorrect. The following snippet, works even with C++98/03 and I am pretty much avoiding everything fancy, I just follow simple rules the language has since time immemorial with regular function template overload syntax and ordering tricks:
#include <cstdio> #include <utility> template<typename A, typename B> void function(std::pair<A,B>) { printf("different\n"); } template<typename A> void function(std::pair<A,A>) { printf("same\n"); } int main() { function(std::pair<int,long>()); function(std::pair<int,int>()); return 0; }
void function(std::pair<auto, auto>) { printf("different\n"); } template<typename A> void function(std::pair<A, A>) { printf("same\n"); }
Regarding your concerns on the original example of std::pair<auto, auto>, my proposal doesn't really change anything: if you wanted to express the constraint that the types must be different *today*, you would still have to resort to static assertions and decltype, so I believe what I'm after doesn't make the situation worse.
I know that your proposal does not change anything - because per Ville's reference it does not add anything. Also the examples I have laid out show quite eloquently that you could express that types must be different yesterday. Ville rhetorically asked, in the context of your OP of how he would express the notion of two different types in that construct. Despite some people may take this personally, it is technically obvious that with 'auto' used that way we only have a pointless shorthand favoring latent typing (again...); canonical template notation is still superior in covering all cases, even when no SFINAE tricks are involved.
Yes, we can now close this thread.
OK, but why wouldn't the same technique work with auto?
void function(std::pair<auto, auto>) { printf("different\n"); } template<typename A> void function(std::pair<A, A>) { printf("same\n"); }
void function(std::pair<auto{A}, auto
{B}>) { static_assert(!std::is_same<A,B>::value, "they cannot be the same!"); printf("different\n"); }
I don't understand why you say it doesn't add anything. It allows you writing "auto" where it was not previously allowed, without making the situation worse. If it didn't add anything, the Concepts TS would probably not bother allowing it. On a language level, it simply completes a parallel between auto type deduction and template type deduction which only went half-way before.
Yes, we can now close this thread.
Cool, we all agree :)
Thank you for your comments anyway,
Andy
On 2 October 2014 20:38, George Makrydakis <irreq...@gmail.com> wrote:OK, but why wouldn't the same technique work with auto? void function(std::pair<auto, auto>) { printf("different\n"); } template<typename A> void function(std::pair<A, A>) { printf("same\n"); } You'd have to introduce another, pretty weird rule for partially orderingYou don't have to introduce anything. The concepts proposal's working version already includes a specification how such an abbreviated function translates to a function template, and the partial ordering suggested by Andy already works.
as it is, it is not a 1:1 correspondence for every scenario. Take it only as that. Also, do consider what Ville wrote about 'concepts' authors working on extending auto, you wouldn't like to waste your time for something they are doing secretly since they have more leverage, regardless of any actual worth"Secretly"? Does https://github.com/cplusplus/concepts-ts/ perhaps not work for you?
Based on a very new working draft that is not yet published, yes, I am sure.
I took the example I pasted from that draft
On 2 October 2014 21:43, George Makrydakis <irreq...@gmail.com> wrote:"Secretly"? Does https://github.com/cplusplus/concepts-ts/ perhaps not work for you? For informing you of your "not published yet" policy for things you guys limit access, this comes from your message Ville: https://groups.google.com/a/isocpp.org/d/msg/std-proposals/klC8PjzRNzI/FkZf3Wv7620J On 10/02/2014 01:13 PM, Ville Voutilainen wrote: Based on a very new working draft that is not yet published, yes, I am sure. I took the example I pasted from that draftIt so happens that that draft is apparently public, since the version in that repository contains the very example I quoted. So you can look at how the new auto semantics work just fine, if you happen to look at the non-secret work that is happening in that repository.
Regarding the internal mailing lists, yes, there are communication facilities of the committee that are not public, and these forums have provided ample reason to keep things that way.
You seem to be the last person to lecture about "derailing into off-topicness", as far as I can see.
On 10/02/2014 09:58 PM, Ville Voutilainen wrote:
On 2 October 2014 21:43, George Makrydakis <irreq...@gmail.com> wrote:"Secretly"? Does https://github.com/cplusplus/concepts-ts/ perhaps not work for you? For informing you of your "not published yet" policy for things you guys limit access, this comes from your message Ville: https://groups.google.com/a/isocpp.org/d/msg/std-proposals/klC8PjzRNzI/FkZf3Wv7620J On 10/02/2014 01:13 PM, Ville Voutilainen wrote: Based on a very new working draft that is not yet published, yes, I am sure. I took the example I pasted from that draftIt so happens that that draft is apparently public, since the version in that repository contains the very example I quoted. So you can look at how the new auto semantics work just fine, if you happen to look at the non-secret work that is happening in that repository.
Exactly where I want you. You seem to be assuming that there is no "secret" work happening as the default, which is quite the opposite.
Also, do consider what Ville wrote about 'concepts' authors working on extending auto, you wouldn't like to waste your time for something they are doing secretly since they have more leverage, regardless of any actual worth of any argument they put through...
That is the end-pit of concepts. Not the fountain. This is not the thread for starting a real hellfire of certain quite galant and generous EWG practices of which I do have first hand experience. You also are aware of how things are "delegated" aren't you. So let's leave it there as it is of little concern to "outsiders".
Regarding the internal mailing lists, yes, there are communication facilities of the committee that are not public, and these forums have provided ample reason to keep things that way.
Here we go. Thanks for providing citable feedback on the fact that these public lists are only considered a gimmick and that things are decided in your private EWG quarters.
As long as these lists provide you marketing pool to sell your "open" character, they serve their purpose. You do not really need the ideas presented by true outsiders here. You guys don't really have respect for all volunteers, just for your "volunteers" - and that is my first-hand experience.
You seem to be the last person to lecture about "derailing into off-topicness", as far as I can see.
Everytime you will be defensive of current EWG practices with me, "you" will be getting your disarming reply, on-topic or off-topic given that "you" did not respect "your" rules when you had to.
This has nothing to do with you as a person (you are an ok guy), but as an EWGer, you won't be able to defend those practices. Since all of you EWGers will be more careful from now on and follow your own rules, I think that something is gained for any contributors that may come. I gain zero out of this.
Other than that, again you are a valid technical commenter I respect on the things you really do know about. I will gladly accept to be proven wrong by you on a really technical subject. No point in continuing to go offtopic dear Ville. Let's close all of it here.
The technical aspects in C++ are interesting, only that they are deeply poisoned by social manure and pomposity.
People work on papers. They may or may not have a web cam pointed at their keyboards so you can watch them type. They may or may not put them on public repos while they are working on them. They may or may not send drafts to their friends. They may or may not send drafts to the internal committee mailing lists. They may or may not send drafts to this list. At some point, if they wish to present it, they will get an N-number and it will be published as part of a mailing.
I don't see how any of that is secret. That is just how people work, and different people work differently.
You keep saying that, but it sure looks like you'd rather get the last word in instead of winding it down. Closing a discussion is easy, and doesn't require any drama whatsoever. Just stop posting on the topic. If others keep going, just mute the conversation.The technical aspects in C++ are interesting, only that they are deeply poisoned by social manure and pomposity.
Continually using words like "social manure and pomposity" to describe the Committee poisons this list, at least for me.