9
  • list's end() returns a copy of the past-the-end iterator, right?
  • Therefore, list.end() is an rvalue, right?
  • the -- operator-function overloaded for list iterator takes a non-const reference, right?
  • you can't bind rvalues to non-const references, right?

So how come does

std::list<int> lst;
// ... 
--l.end();` 

compile?

As correctly pointed out, my third point is not necessarily right. But then how about this code which also compiles?

struct A{};

void f(A&)
{

}
A a()
{
    return A();
}

int main()
{
    f(a());
}
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434

1 Answers1

12
  • the -- operator-function overloaded for list iterator takes a non-const reference, right?

This point is wrong. The operator-- is a member function, and a member function can be invoked on a temporary. You don't pass any object to this member function as argument. so the question of binding rvalue to non-const reference doesn't arise in the first place.


As for the edit (passing rvalue to f(A&){}), it is a non-standard extension. I guess you're using Microsoft Compiler, because I know it has this non-standard extension which is stupid in my opinion.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Oh... right :) I'm silly. The resto of the logic is sound thouhg, isn't it? :) – Armen Tsirunyan Feb 27 '13 at 16:40
  • Btw, does the standard mandate that -- be a member? Or is it implementation-defined? – Armen Tsirunyan Feb 27 '13 at 16:44
  • Actually it is not necessarily a member function. The iterator could be a pointer. – Andy Prowl Feb 27 '13 at 16:44
  • 1
    @AndyProwl: It is a `std::list`, so it cannot be a pointer (I don't think so). – Nawaz Feb 27 '13 at 16:44
  • @AndyProwl: vector's iterator may be and **is** a pointer on most implementations (in release mode) – Armen Tsirunyan Feb 27 '13 at 16:46
  • @Nawaz: But then the OP's example could make sense for `std::vector`, right? – Andy Prowl Feb 27 '13 at 16:46
  • @AndyProwl: If it were a vector and iterator were a pointer then -- wouldn't be a function, but an operator, and the standard mandates that --'s operand be an lvalue, so --v.end() would not compile – Armen Tsirunyan Feb 27 '13 at 16:47
  • @ArmenTsirunyan: Exactly, so it would be implementation-dependent. So that means `--v.end()` is not portable. Interesting. – Andy Prowl Feb 27 '13 at 16:49
  • @ArmenTsirunyan, I was quite surprised to find you were right. I didn't expect to not be able to use `operator--` on a temporary, even if the operation had no observable side effects. http://ideone.com/als0zi – Mark Ransom Feb 27 '13 at 16:53
  • @ArmenTsirunyan: Updated my answer addressing the edit in your question. Let me know if you're really using MSVC++? – Nawaz Feb 27 '13 at 16:57
  • Btw by that MSVC++ extention, any rvalue can be passed as non-const reference or only temps? – Slava Feb 27 '13 at 17:02
  • In C++11 a member function can be invoked on an rvalue only if that member is declared with no ref-qualifier or with a ref-qualifier of "&&". It is theoretically possible for an implementation of std::list::iterator to declare a member `iterator& operator -- () &` so that the operator cannot be invoked on rvalues. – Casey Feb 27 '13 at 21:05
  • @Casey: That is not C++11. That is just *a proposal* for C++1y. – Nawaz Feb 28 '13 at 06:20
  • In my copy of the standard, 13.3.1 [over.match.funcs] p5 states: "For non-static member functions declared without a ref-qualifier, an additional rule applies: even if the implicit object parameter is not const-qualified, an rvalue can be bound to the parameter as long as in all other respects the argument can be converted to the type of the implicit object parameter." The clear implication is that binding an rvalue to the implicit this parameter of a non-static member function declared with a "&" ref-qualifier is not allowed. – Casey Feb 28 '13 at 22:51
  • @Casey: Which copy of the draft you've? n3485? – Nawaz Mar 01 '13 at 02:12
  • @Casey: Can you start a thread about what you're saying. I'm a bit confused. As far as I know member-function such as `void f() &&` is a proposal for next Standard only (and that is what is referred to as "ref-qualifier", I suppose?). – Nawaz Mar 01 '13 at 18:59
  • Yes, the trailing "&" or "&&" in a non-static member function declaration is a ref=qualifier, see 8 [dcl.decl] p4. Searching through the standard for occurrences of the phrase "ref-qualifier" will get you the gist of the feature. This was proposal N2439 for C++0x, and it did make the standard. To my knowledge no compiler implements it yet. – Casey Mar 01 '13 at 19:56
  • Correction: looks like Clang implements it according to http://clang.llvm.org/cxx_status.html since version 2.9. – Casey Mar 01 '13 at 20:08