The overloading of keywords in C++ is often cited as a nasty problem (c.f. "static", which means a half-dozen different things in different contexts). An even nastier problem is that we can't add any new keywords without breaking user code, which makes future language extensions difficult. There is, however, at least one keyword hanging around which is underloaded**: "auto".
auto is a syntactic relic from 'C' whose use is never neccessary. It can be used as a storage class specifier (just like "static") to mean, informally, "put this on the stack". Since variables are put on the stack by default in all contexts where "auto" can be used, it is completely redundant to write auto and everyone*** leaves it out. As long as we have "auto", however, I think we ought to put it to work.
Proposed usage #1 =================
We've all probably been bitten by the rule that "if it looks like a function declaration, it is a function declaration" (6.8 in the standard). This example borrowed from Herb Sutter at http://www.gotw.ca/gotw/075.htm:
Unfortunately, where to place the parentheses is hard to remember (around one argument? around all arguments?), and it is thoroughly non-obvious why the extra parentheses around the argument name (cin) in the first case don't serve to disambiguate it as an expression-statement. Right now, it is a syntax error to write:
auto deque<string> coll3(istream_iterator<string>(cin), // 3 istream_iterator<string>());
because "auto" is an illegal storage class for a function declaration. I propose that #3 become a legal synonym for #2. It's much easier, IMO, to understand how it works in disambiguating the declaration.
Proposed usage #2 =================
In the world of high-performance numeric computation, the use of Expression Templates (http://www.extreme.indiana.edu/~tveldhui/papers/Expression-Templates/... pl.html) allows us to obtain the highest performance from matrix expressions written in natural mathematical notation. Expression Templates work by delaying expression evaluation and allowing the numerics library to examine the structure of the computation at compile time, applying optimizations. The ability to use natural mathematical notation makes for simple code and easier maintenance, but a detail of the C++ type system prevents us from fully realizing that goal.
Expression templates generate complicated types which encapsulate the expression's parse tree. An example from the paper referenced above:
the expression "(a+b)/(c-d)" is of type DVExpr<DVBinExprOp<DVExpr< DVBinExprOp<DVec::iterT, DVec::iterT, DApAdd>>, DVExpr<DVBinExprOp< DVec::iterT, DVec::iterT, DApSubtract>>, DApDivide>>
It is a common rule that for readable and maintainable code, complicated expressions should be broken up into smaller ones, but with expression templates this is obviously impractical, because we would have to declare variables to hold intermediate results. If (a+b)/(c-d) were part of a larger expression that we wanted to evaluate separately, we'd have to declare an intermediate variable of the type shown above. I propose that the "auto" keyword be available to declare variables whose type is deduced from the type of the expression with which they are initialized:
auto tmp = (a+b)/(c-d);
Allowing this usage would neatly solve the problem described above, and would make a neat companion to the proposed typeof() keyword.
-Dave
** credit to Andy Sawyer for first applying the "underloaded" label to "auto" *** I have never seen a program outside of a book on the language that used "auto"
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
"David Abrahams" <abrah...@mediaone.net> wrote in <052201c0b4ab$603e8050$0500a...@dragonsys.com>:
>The overloading of keywords in C++ is often cited as a nasty problem >(c.f. "static", which means a half-dozen different things in >different contexts). An even nastier problem is that we can't add >any new keywords without breaking user code, which makes future >language extensions difficult. There is, however, at least one >keyword hanging around which is underloaded**: "auto".
[snip]
I like proposed usage #2 most!! Finally I can write:
vector<int> v; for (auto i=v.begin(); i!=v.end(); i++) { ... ]
But I have a different suggestion for #2, that would involve an overload of the template keyword.
Take the example above. I'd suggest that one can write: vector<int> v; for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
This usage of template instructs the compiler to deduce T as the type of v.begin() and use T as the type to declare i. In other words, using template in a variable declaration works quite the way as 'template' in a template function declaration. The nice thing is, that T is now a typename which is valid for the scope of the declaration, which means, that I can do things like these:
int k; // declares int i and vector<int> vi; template<typename T> T i=k, vector<T> vi;
// declares vector<int> &k and int x; template<typename K> vector<K> &k=vi, K x;
// declares vector<int>::iterator it and int r template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;
'auto' could then be useful as a identifier placeholder for interference:
int inarray[10]; /* If I want to decompose the type of inarray, I'd need to declare an identifier here, which is needed to build the expressions tree on which the deduction takes place. 'auto' plays the role of an "anonymous" identifier, which isn't really declared. */ template<typename Type,int Size> Type auto[Size]=intarray;
/* The deduction introduces "Type" as int and Size as a const integer expression which is valued 10. */ double p[Size]; /* declare an array of the same size of inarray. This looks much better than 'double p[sizeof(inarray)/sizeof(int)]' */ vector<Type> t; /* a vector<int> */
Comments? Suggestions?
-- Marco
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
David Abrahams <abrah...@mediaone.net> wrote: > Proposed usage #1 [...] > Right now, it is a > syntax error to write:
> auto deque<string> coll3(istream_iterator<string>(cin), // 3 > istream_iterator<string>());
> because "auto" is an illegal storage class for a function declaration. I > propose that #3 become a legal synonym for #2. It's much easier, IMO, to > understand how it works in disambiguating the declaration.
I sincerely hope that this proposal makes its way into the language. It solves a real problem. Adding a "redundant" pair of parenthesis is, frankly, embarassing. As this construction idiom becomes more and more common, C++ will look more and more like these issues weren't thought all the way through.
For what it's worth, the last time I had to explain this particular ambiguity to a group of students, a group of them told me that they had tried on their own initiative to resolve the ambiguity by adding "auto" to their code in exactly this manner, because "it seemed like the obvious thing to do." !!
Luck++; Phil
-- pedwards at disaster dot jaj dot com | pme at sources dot redhat dot com devphil at several other less interesting addresses in various dot domains The gods do not protect fools. Fools are protected by more capable fools.
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
I think this is an outstanding proposal. Thus I'll do my best to play devil's advocate and attempt to find problems with it.
"David Abrahams" <abrah...@mediaone.net> once said:
>serve to disambiguate it as an expression-statement. Right now, it is a >syntax error to write:
> auto deque<string> coll3(istream_iterator<string>(cin), // 3 > istream_iterator<string>());
>because "auto" is an illegal storage class for a function declaration. I >propose that #3 become a legal synonym for #2. It's much easier, IMO, to >understand how it works in disambiguating the declaration.
Does this work (not do anything "bad") for declaring function pointers, and/or references too? (I think it does, but declaring pointers to functions, and declaring functions that return pointers to array fo functions and horrible things like that... it's all beyond my general understanding. So my real question is something like "can you rewrite the grammar to ensure this is possible without causing new ambiguities?" I think yes, but it would strengthen the proposal much to do so.)
(As an aside, I am curious why function declarations are even allowed inside functions.)
>In the world of high-performance numeric computation, the use of Expression >Templates >(http://www.extreme.indiana.edu/~tveldhui/papers/Expression-Templates/... >pl.html) allows us to obtain the highest performance from matrix expressions >written in natural mathematical notation. Expression Templates work by >delaying expression evaluation and allowing the numerics library to examine >the structure of the computation at compile time, applying optimizations. >The ability to use natural mathematical notation makes for simple code and >easier maintenance, but a detail of the C++ type system prevents us from >fully realizing that goal.
>Expression templates generate complicated types which encapsulate the >expression's parse tree. An example from the paper referenced above:
>the expression "(a+b)/(c-d)" is of type >DVExpr<DVBinExprOp<DVExpr< DVBinExprOp<DVec::iterT, DVec::iterT, DApAdd>>, >DVExpr<DVBinExprOp< DVec::iterT, DVec::iterT, DApSubtract>>, DApDivide>>
>It is a common rule that for readable and maintainable code, complicated >expressions should be broken up into smaller ones, but with expression >templates this is obviously impractical, because we would have to declare >variables to hold intermediate results. If (a+b)/(c-d) were part of a larger >expression that we wanted to evaluate separately, we'd have to declare an >intermediate variable of the type shown above.
Note also that expression-templates are not the only place this crops up. In the FC++ library, "direct functoids" which are created via currying and composition also exhibit this same problem all the time. Also, I have experienced this problem when using the View Template Library. So, to any other readers: don't think that this is a solution that "only helps the expression-template people". This is a common problem that arises in a number of disparate domains (which have only "templates" in common). And the problems apply to client/user code-- not just to implementation code that's hidden inside these libraries.
>I propose that the "auto" >keyword be available to declare variables whose type is deduced from the >type of the expression with which they are initialized:
>auto tmp = (a+b)/(c-d);
>Allowing this usage would neatly solve the problem described above, and >would make a neat companion to the proposed typeof() keyword.
Terrific. My hunch is that all of us waiting on the typeof() keyword (and there are a fair number of us) were about to add
#define DECLARE(var,value) ; typeof(value) var = value;
or some similar horror to try to deal with this. Your idea is a much better way to deal with this.
But as promised, I must try to break it. So,
First: are you sure this doesn't conflict with the first proposal (the deque example)? I think it's ok. However...
Second: Instead of and/or in addition to auto tmp = (a+b)/(c-d); should auto tmp( (a+b)/(c+d) ); be allowed too? This allows for "explicit" constructors, too. It might be a shame if "magic 'auto' typing" only worked for types with implicit copy constructors.
Third: Is there a way to add cv-qualifiers or reference-ness? In other words, can I do something like auto const& tmp = (a+b)/(c-d); This would also be nice, as well as potentially more practical for some of the intended uses. (There aren't any "implicit int"s left in the language trying to get in the way, are there?)
Fourth: If either "Second" or "Third" or both look ok, do the combinations of the new proposals create any new ambiguity? (In other words, if my added suggestions pass, "First" must be revisited.)
I thought my Error<compile_time_bool,"User defined conditional error message"> idea was good--but this one is even better! If any compiler implementor adds both this extension and my user-defined error messages idea, I will be happy to purchase that compiler and quit using g++, even if I have to pay out the nose. I am dying for these features!
-- Brian M. McNamara lor...@acm.org : I am a parsing fool! ** Reduce - Reuse - Recycle ** : (Where's my medication? ;) )
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
In article <Xns906FC4EAFCB49marcotechnob...@technoboredom.net>, Marco Manfredini <ma...@technoboredom.net> writes
>But I have a different suggestion for #2, that would involve an overload >of the template keyword.
>Take the example above. I'd suggest that one can write: >vector<int> v; >for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
>This usage of template instructs the compiler to deduce T as the type of >v.begin() and use T as the type to declare i. In other words, using >template in a variable declaration works quite the way as 'template' in >a template function declaration.
uses of the 'template' keyword are already ugly enough as well as dealing with one of the more complex areas of the language so I would not advocate any more meanings for it, not now, not ever.
-- Francis Glassborow See http://www.accu.org for details of The ACCU Spring Conference, 2001 (includes many regular participants to C & C++ newsgroups)
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> But I have a different suggestion for #2, that would involve an overload > of the template keyword.
> Take the example above. I'd suggest that one can write: > vector<int> v; > for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
> This usage of template instructs the compiler to deduce T as the type of > v.begin() and use T as the type to declare i. In other words, using > template in a variable declaration works quite the way as 'template' in > a template function declaration. The nice thing is, that T is now a > typename which is valid for the scope of the declaration, which means, > that I can do things like these:
> int k; > // declares int i and vector<int> vi; > template<typename T> T i=k, vector<T> vi;
> // declares vector<int> &k and int x; > template<typename K> vector<K> &k=vi, K x;
> // declares vector<int>::iterator it and int r > template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;
People have been proposing the use of a typeof() operator for this purpose
int k; // declares int i and vector<int> vi; auto i=k, vector<typeof(i)> vi;
// declares vector<int> &k and int x; typeof(vi) &k=vi; vi::value_type x;
// declares vector<int>::iterator it and int r auto it=k.begin(), iterator_traits<typeof(it)>::value_type &r;
I guess I prefer the use of auto with typeof in most cases. It seems much simpler.
> 'auto' could then be useful as a identifier placeholder for > interference:
> int inarray[10]; > /* If I want to decompose the type of inarray, I'd need to declare an > identifier here, which is needed to build the expressions tree on which > the deduction takes place. 'auto' plays the role of an "anonymous" > identifier, which isn't really declared. */ > template<typename Type,int Size> Type auto[Size]=intarray;
Okay, now I really don't like the proposal. The fact that this doesn't really initialize a variable, but instead produces a compile-time const int really rubs me the wrong way.
> /* The deduction introduces "Type" as int and Size as a const integer > expression which is valued 10. */ > double p[Size]; /* declare an array of the same size of inarray. This > looks much better than 'double p[sizeof(inarray)/sizeof(int)]' */ > vector<Type> t; /* a vector<int> */
This bit is a problem with a known, existing solution in the current C++ language.
-Dave
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! <gt51...@prism.gatech.edu> writes
>(As an aside, I am curious why function declarations are even allowed >inside functions.)
Almost certainly for compatibility with C.
-- Francis Glassborow See http://www.accu.org for details of The ACCU Spring Conference, 2001 (includes many regular participants to C & C++ newsgroups)
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
gt51...@prism.gatech.edu (Brian McNamara!) wrote in <99l3nf$7n...@news-int.gatech.edu>:
>Third: Is there a way to add cv-qualifiers or reference-ness? In >other words, can I do something like > auto const& tmp = (a+b)/(c-d); >This would also be nice, as well as potentially more practical for >some of the intended uses. (There aren't any "implicit int"s left >in the language trying to get in the way, are there?)
I think auto could be positioned as a placeholder for the right-hand type. Such that: {X}={Y};
can be rewritten as
{X/auto=typeof(Y)}=Y;
In that case cv would come up quite naturally, like:
const auto & tmp = (a+b)/(c-d);
Anything else looks more complicated, since whatever type I declare on the lhs, it must be initializable with the rhs.
>I thought my > Error<compile_time_bool,"User defined conditional error message"> >idea was good--but this one is even better! If any compiler >implementor adds both this extension and my user-defined error >messages idea, I will be happy to purchase that compiler and quit >using g++, even if I have to pay out the nose. I am dying for these >features!
g++ already has typeof() and I think that auto can be hacked into it easily (for someone who is into the source).
-- Marco
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> I sincerely hope that this proposal makes its way into the language.
Same hope here with addition "ASAP". And in company of typeof().
Paul
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! > <gt51...@prism.gatech.edu> writes > >(As an aside, I am curious why function declarations are even allowed > >inside functions.)
> Almost certainly for compatibility with C.
Would it be sensible to consider deprecating this feature, or removing it altogether? It seems to give no significant benefit, and plenty of pain.
-- James Dennett
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
David Abrahams wrote: > Okay, now I really don't like the proposal. Francis Glassborow wrote: > uses of the 'template' keyword are already ugly enough as well as > dealing with one of the more complex areas of the language so I would > not advocate any more meanings for it, not now, not ever.
Oh boy, good that I'm going on vacation on thursday - I feel like a loony making stupid rants that everybody hates :-)
Just for the records, I felt it was a good idea, when I remembered from my CS student & scheme days, that local variable declarations (and everything else) can easily be transformed into nestes functions . Having this in my lobe, I found function templates and declaration "templates" are the same thing too -- and I really found it *beautiful*
-- Marco
And everything must be LAMBDA-CALCULUS when I'm back!! Listen!!!
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
In article <3ABF4E68.14646...@acm.org>, James Dennett <jdenn...@acm.org> writes
>Francis Glassborow wrote:
>> In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! >> <gt51...@prism.gatech.edu> writes >> >(As an aside, I am curious why function declarations are even allowed >> >inside functions.)
>> Almost certainly for compatibility with C.
>Would it be sensible to consider deprecating this feature, >or removing it altogether? It seems to give no significant >benefit, and plenty of pain.
I think the pain would still be there unless you want to deprecate member function declarations in classes:)
-- Francis Glassborow See http://www.accu.org for details of The ACCU Spring Conference, 2001 (includes many regular participants to C & C++ newsgroups)
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> > In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! > > <gt51...@prism.gatech.edu> writes > > >(As an aside, I am curious why function declarations are even allowed > > >inside functions.)
> > Almost certainly for compatibility with C.
> Would it be sensible to consider deprecating this feature, > or removing it altogether? It seems to give no significant > benefit, and plenty of pain.
The "benefit" is the ability to do overloaded function selection in a local scope, by utilizing the name hiding phenomenon. For example, the program...
void f(int); void f(bool);
void main() { void f(bool);
f(1); f(false);
}
... changes its behaviour when the declaration inside the main()'s function block is removed.
Cheers!
- Risto -
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> > In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! > > <gt51...@prism.gatech.edu> writes > > >(As an aside, I am curious why function declarations are even allowed > > >inside functions.)
> > Almost certainly for compatibility with C.
> Would it be sensible to consider deprecating this feature, > or removing it altogether? It seems to give no significant > benefit, and plenty of pain.
I would like to see it extended to allow proper nested functions, and (whilst I'm at it) for local classes to have linkage so they can be used with templates.
Anthony -- Anthony Williams Software Engineer, Nortel Networks Optoelectronics The opinions expressed in this message are not necessarily those of my employer
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> > > In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! > > > <gt51...@prism.gatech.edu> writes > > > >(As an aside, I am curious why function declarations are even allowed > > > >inside functions.)
> > > Almost certainly for compatibility with C.
> > Would it be sensible to consider deprecating this feature, > > or removing it altogether? It seems to give no significant > > benefit, and plenty of pain.
> The "benefit" is the ability to do overloaded function > selection in a local scope, by utilizing the name hiding > phenomenon.
I'm glad you wrote "benefit" in quotation marks. I'd love to get rid of such ugly code at the same time as fixing a real problem.
> For example, the program...
> void f(int); > void f(bool);
> void main() > { > void f(bool);
> f(1); > f(false); > }
> ... changes its behaviour when the declaration inside > the main()'s function block is removed.
int main, blah blah blah.
-- James Dennett
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> In article <3ABF4E68.14646...@acm.org>, James Dennett <jdenn...@acm.org> > writes > >Francis Glassborow wrote:
> >> In article <99l3nf$7n...@news-int.gatech.edu>, Brian McNamara! > >> <gt51...@prism.gatech.edu> writes > >> >(As an aside, I am curious why function declarations are even allowed > >> >inside functions.)
> >> Almost certainly for compatibility with C.
> >Would it be sensible to consider deprecating this feature, > >or removing it altogether? It seems to give no significant > >benefit, and plenty of pain.
> I think the pain would still be there unless you want to deprecate > member function declarations in classes:)
How so? It's not legal to initialize non-static data members of classes, so there's no chance of confusing an initialized data member with a method declaration. The only initializations we allow in class definitions are for integral types, IIRC. As far as I can see, there's no possibility of the problematic ambiguity arising inside a class definition.
If I'm wrong, I'm sure you (or another language lawyer ;) will detail why.
-- James Dennett
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Manfredini) wrote: >"David Abrahams" <abrah...@mediaone.net> wrote in ><052201c0b4ab$603e8050$0500a...@dragonsys.com>:
>>The overloading of keywords in C++ is often cited as a nasty problem >>(c.f. "static", which means a half-dozen different things in >>different contexts). An even nastier problem is that we can't add >>any new keywords without breaking user code, which makes future >>language extensions difficult. There is, however, at least one >>keyword hanging around which is underloaded**: "auto". >[snip]
>I like proposed usage #2 most!! Finally I can write:
>But I have a different suggestion for #2, that would involve an overload >of the template keyword.
>Take the example above. I'd suggest that one can write: >vector<int> v; >for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
>This usage of template instructs the compiler to deduce T as the type of >v.begin() and use T as the type to declare i.
Sorry I disagree with both suggestions.
For example (a generic version of the above);
StartT start =...; EndT end = ...; for (template<typename T> T i=start; i!=end; i++) { ... }
What if start and end are different types? What should T be? StartT? EndT? Another compatible type? Too complex for a compiler and/or user to determine IMHO.
Rather than
for (template<typename T> T i=v.begin(); i!=v.end(); i++) { ... }
how about
for (v::iterator i=v.begin(); i!=v.end(); i++) { ... }
>In other words, using >template in a variable declaration works quite the way as 'template' in >a template function declaration. The nice thing is, that T is now a >typename which is valid for the scope of the declaration, which means, >that I can do things like these:
>int k; >// declares int i and vector<int> vi; >template<typename T> T i=k, vector<T> vi;
>// declares vector<int> &k and int x; >template<typename K> vector<K> &k=vi, K x;
>// declares vector<int>::iterator it and int r >template<typename X> X it=k.begin(), iterator_traits<X>::value_type &r;
I can't see the value in the above apart from adding more complexity to the language. Could you give examples on how the above are used, and not just declared. Do you gain anything?
>'auto' could then be useful as a identifier placeholder for >interference:
>int inarray[10]; >/* If I want to decompose the type of inarray, I'd need to declare an >identifier here, which is needed to build the expressions tree on which >the deduction takes place. 'auto' plays the role of an "anonymous" >identifier, which isn't really declared. */ >template<typename Type,int Size> Type auto[Size]=intarray;
Think of it from a design pov. Why is inarray 10 elements? Why are they ints? IMHO you should build complex types from basic types, not the other way around.
>/* The deduction introduces "Type" as int and Size as a const integer >expression which is valued 10. */ >double p[Size]; /* declare an array of the same size of inarray. This >looks much better than 'double p[sizeof(inarray)/sizeof(int)]' */ >vector<Type> t; /* a vector<int> */
>Comments? Suggestions?
I'm not conviced.
Regards Mark
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
David Abrahams wrote: >I propose that the "auto" >keyword be available to declare variables whose type is deduced from the >type of the expression with which they are initialized: >auto tmp = (a+b)/(c-d);
First of all, I'd like to note that there's yet another use of 'auto' the original post hasn't mentioned:
template<class T1, class T2> auto foo(const T1& t1, const T2& t2) { return t1 + t2; }
Such feature would greatly facilitate writing lambda libraries and their use. Actulually, I'd like to see lambda keyword in the language tomorrow, but that been impossible, auto is simple to implement and usefull addition for now.
Second, it seems to me that 'auto' is little misleading. Better name would be 'infered', according to functional programming terms.
Mark Blewett wrote:
> Sorry I disagree with both suggestions.
> For example (a generic version of the above);
> StartT start =...; > EndT end = ...; > for (template<typename T> T i=start; i!=end; i++) { ... }
> What if start and end are different types? What should T be? StartT? > EndT? Another compatible type? Too complex for a compiler and/or user > to determine IMHO.
Not at all! Precise semantic for auto/infered can be similar to that already given in post by Marco Manfredini:
1) auto/infered can only appear in definition of variable with initializer or in function definition, at position where type name is allowed by the grammar.
... infered ... var = e; is equvivalent to ... typeof(e) ... var = e; Such semantic means that 'infered' is *nothing but syntax sugar*, but a very good one.
2) for functions returning expressions e1, en, it should hold that typeof(e1) == ... == typeof(en) and infered will be the same at typeof(e1)
Compiler can apply those rules very easily.
> how about > for (v::iterator i=v.begin(); i!=v.end(); i++) { ... }
That's just the same as for (typeof(v)::iterator .....) so this is another syntax sugar. Don't know whether we need it.
-- Regards, Vladimir
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
What about creating static variables without knowing their type.
Andrei
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> >I propose that the "auto" > >keyword be available to declare variables whose type is deduced from the > >type of the expression with which they are initialized:
> >auto tmp = (a+b)/(c-d);
> First of all, I'd like to note that there's yet another use of 'auto' the > original post hasn't mentioned:
I note firstly that my original proposal has a weakness: it is not really appropriate for inferred type declarations at namespace scope, since the 'auto' has an existing meaning as a storage class.
That said, I don't like the proposal above too much because 'auto' might conflict with the storage class of the return value in this case, and you can't declare a function's storage class to be auto (see the original post). On the other hand, since 'auto' is really optional, it might make sense to expand the places where it is legal.
Your proposal also has another, more important problem: the interface of the function is tied to the implementation more strongly than:
The compiler should be able to deduce the return type of a function template from its declaration alone. On the other hand, the above requires T1 and T2 to be default-constructible, which is an undesired constraint. I'm not sure what the best solution for this case might be. Maybe the compiler should be allowed to use names from the argument list in typeof() expressions for the return type:
> Such feature would greatly facilitate writing lambda libraries and their > use. Actulually, I'd like to see lambda keyword in the language tomorrow, > but that been impossible, auto is simple to implement and usefull addition > for now.
> Second, it seems to me that 'auto' is little misleading. Better name would > be 'infered', according to functional programming terms.
Well, yes, that's part of my argument against it in this case - it doesn't indicate storage class. All the same, adding new keywords is problematic because it breaks existing code.
-Dave
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
In article <aji1a9.kp...@158.250.10.247>, Vladimir Prus <gh...@cs.msu.su> writes
>Second, it seems to me that 'auto' is little misleading. Better name would >be 'infered', according to functional programming terms.
But we have to be very careful about introducing new keywords. However at a recent BSI C++ Standards Panel meeting (held in an Oxford hostelry, which may be significant) we realised that we have a whole raft of potential keywords that will not possibly break existing code. Consider:
#include <algorithm> using namespace std; ~using std::sort;
Do I even need to explain what such code would do? :)
And think how useful a ~using directive would be to undo the damage caused by an idiot programmer who has used using directives inappropriately.
-- Francis Glassborow See http://www.accu.org for details of The ACCU Spring Conference, 2001 (includes many regular participants to C & C++ newsgroups)
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> #include <algorithm> > using namespace std; > ~using std::sort;
> Do I even need to explain what such code would do? :)
Hey, that looks nice and useful! I really like the idea. And I would even take the opportunity to suggest a very simple change in the grammar of the language to allow using declarations to be given a list of symbols, instead of a single one. This, of course, would also apply to ~using.
// The way we must do now: #include <iostream> using std::cin; using std::cout; using std::endl;
// How it could be: #include <iostream> using std::cin, std::cout, std::endl;
// Same for ~using: #include <algorithm> ~using std::sort, std::slice;
This is something I have wished for long and Mr. Francis' post just reminded me of that.
Best regards,
Ney André de Mello Zunino.
"Take of the fruit, But guard the seed..."
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
David Abrahams wrote: >> First of all, I'd like to note that there's yet another use of 'auto' > the >> original post hasn't mentioned:
>> template<class T1, class T2> >> auto foo(const T1& t1, const T2& t2) >> { >> return t1 + t2; >> } > Your proposal also has another, more important problem: the interface of > the function is tied to the implementation more strongly than:
> The compiler should be able to deduce the return type of a function > template from its declaration alone.
This is not exactly what I propose. 'inferred' should be allowed as return type *only* if body is given. Really, this requires some change to the language semantics.
template<class T> struct S { int f1() {} infered f2() { .... } template<class T2> something<T2> f3() { ... } }; Here f2 is not a member template, but the declaration can be fully known only when f2 is instantinated, and not when S is instantinated, as is the case with f1. But I don't see any better way. (BTW another proposed syntax, template<typename T> T f2() {} more clearly indicates semantics, but it is too verbose for me)
>> Second, it seems to me that 'auto' is little misleading. Better name >> would be 'infered', according to functional programming terms.
> Well, yes, that's part of my argument against it in this case - it doesn't > indicate storage class. All the same, adding new keywords is problematic > because it breaks existing code.
Is there any choice? Lambda libraries now try to provide construct *parallel* to those present in language. Of course they have wierd look, not powerfull enough and don't always work. I think that adding a keyword or two might be better.
-- Regards, Vladimir
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
"Francis Glassborow" <francis.glassbo...@ntlworld.com> wrote in message news:4ZvL68C9O6x6Ew$F@ntlworld.com... > #include <algorithm> > using namespace std; > ~using std::sort;
> Do I even need to explain what such code would do? :)
Will that apply to all sorts of nemes? Like in the situation:
{ Object x; // ... set up x; const typeof(x) & x_ = x; ~using x; // hides x
}
?
Paul
--- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]