TITLE: References are not "first class types" PROBLEM: kanze@us-es.sel.de (James Kanze), 16 Jun 93 I think the above statement is quoted out of context, or perhaps rather, that it is incomplete in the ARM. What is being faded out is the ability to initialize non-const references to refer to a temporary, and not all references. The compiler should still be willing to generate a temporary for a const reference. The justification for this is simple: void f( int& ri ) { ri ++ ; } void someProgram() { unsigned u ; f( u ) ; } Under the old rules, the above was perfectly legal, but since an unsigned is *not* an int, the compiler generated a temporary, and passed a reference to it. It was this temporary that was modified in f, and not the variable 'u'. Which resulted in very surprised programmers. Under the new rules, the above is illegal; if the programmer wants to do it, he must declare himself the int, assign u to it, invoke the function, and then copy the modified temporary back into u. On the other hand, if 'f' did *not* modify 'ri', it should declare the parameter const int&, rather than int&. In this case, the compiler will generate a temporary, since 'f' has stated that it will make no modifications which will be lost. RESPONSE: maxtal@physics.su.OZ.AU (John Max Skaller) [...] [ This first section seems a little specious since it involves a cast from const for the template function f. But I left it for context. -adc ] That is marginally misleading: [ Remember "T const&" is the same as "const T&". -adc ] f( T const& x) { ((T&)x)++; } This code is conforming if and only if T 'has a constructor'. That means its bad for T an 'int', but for say struct complex { float x,y; complex() :x(0), y(0) {} .... }; its perfectly legal and well defined. That means that complex z; f(z); // surprise! because the compiler does *not* make a copy of z. But f(z+1); // no surpise because a copy is created. On the other hand, this cannot happen if you pass by value: g(T x) { x++; } g(z); // no surprise although it depends on how the copy constructor works. [ This is the more interesting part of the posting - the discussion of references and templates. -adc ] It may seem this issue is a non-issue .. until you consider templates. In that case, you might get quite a few surprises. In particular, IMHO the current ARM definition, or at least its interpretation by some compilers, is severely broken: template void f(T x) { x++; cout< void g(T x) { T a=x; // attempted copy a++; cout<