TITLE: Are const rvalues nonsense (especially w/respect to templates)? PROBLEM: maxtal@physics.su.OZ.AU (John Max Skaller) Introducing references is necessary for overloaded operators, and they foul up they type system because they are not really "types". (This is one of the most serious problems, because it couples very strongly to templates) RESPONSE: satish@sun.mcs.clarkson.edu (Satish Thatte) Could you explain this a little further please? What is the connection with templates? RESPONSE: maxtal@physics.su.OZ.AU (John Max Skaller), 21 Dec 94 Templates are parameterised by types. In the ARM, the types int&, int const and int exist, and one can overload on them: f(int); f(int const); int x; int const x2; f(x); // calls f(int) f(x2); // calls f(int const) This is not allowed in ISO C, and it seems clear it is a silly idea -- the "const" in the "int const" parameter has nothing to do with the interface of the function, but is part of the implementation details of the function -- the local parameter is not modified by the function. The ARM has an incomplete, and fairly incomprehensible notion of "trivial conversions" for things like int-->int const, int& --> int, and it had template rules requiring exact matches so that template void f(T); int a; int const b; int& c; int const & d; f(a); // f(int) f(b); // f(int const) f(c); // f(int&); f(d); // f(int const&) This is _really_ bad news. It makes template functions almost unusable. What happens if you write template void g(const T&); g(a); // error g(b); // error g(c); // error g(d); // works This is, well, crap. (no offense). All the calls should work. Now, the committee has taken some steps to fix these problems: a) f(int) and f(const int) declare the same function b) there are no expressions of reference type c) the exact match requirement is weakened d) the trivial conversions have been eliminated e) uncallable instances are excluded from overload resolution f) const CI, where typedef const int CI; is permitted g) member functions can be called on rvalues which have qualified types, ordinary parameters may not h) constructors are non-const Unfortunately, these resolutions were taken ad hoc and not in conformance with a coherent type model. And so while the ARM at least had an almost coherent type model which was barely usable, what we have now is incoherent, and while many cases appear to work better, there are many which are even more inconsistent than before. For example template void f(T a) { T b; } int x; int const y; f(x); // ???????? f(y); // ???????? What happens here? If "const int" is really a type, then there are TWO template instances: void f(int a) { int b; } void f(int const a) { int const b; } and because these two declarations declare the same function, but there are two definitions, then we have an unavoidable breach of program coherence (I.e the ODR). [ ODR = One Definition Rule -adc ] Even if type deduction does not permit "const" types to be deduced like this, there is always the new explicit form: f(x); f(x); I personally believe there is no such thing as a const type. Note in this case that f(..) // error! because the expansion leads to void f(int& a) { int &b; } // error: reference needs initialiser but that is an accident. There are cases where instead the code compiles and completely different semantics are silently provided. Of course there are examples of complete rubbish: template void h() { T const a=0; } h(); // --> int const const a?? (allowed) h(); // --> int const & const a?? (not allowed) This is just one example of how the idea that "int const" is a type leads to problems. ISO C, by the way, has no such rvalue type: it correctly says that constness is an attribute of lvalues only, that is, of the "address" of an object, but not its value. These kind of problems are magified in templates and when various dependent facilities are used together. In order to get orthogonality the basic notions need to be exactly right or we will need huge wads of special cases -- which will turn out to be more or less equivalent to getting the type system right in the first place.