Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should the implementation guard itself against comma overloading?

For example uninitialized_copy is defined in the standard as:

Effects:

for (; first != last; ++result, ++first)   ::new (static_cast<void*>(&*result))     typename iterator_traits<ForwardIterator>::value_type(*first); 

If understood literally, this is a requirement to call operator ,(ForwardIterator, InputIterator). And in fact this code prints Hello world! ten times:

#include <memory> #include <iterator> #include <iostream>   using namespace std;  namespace N {          struct X : iterator<forward_iterator_tag, int> {         pointer _p;         X(pointer p) : _p(p) {}         X& operator++() { ++_p; return *this; }         X operator++(int) { X r(*this); ++_p; return r; }         reference operator*() const { return *_p; }         pointer operator->() const { return _p; }     };           bool operator==(X a, X b) { return a._p == b._p; }     bool operator!=(X a, X b) { return !(a == b); }           void operator,(X a, X b) { cout << "Hello world!\n"; } }  int a[10], b[10];   int main() {     using N::X;     uninitialized_copy(X(a), X(a+10), X(b)); } 

However, for most other algorithms the standard gives the description in prose. E.g. for copy there's no requirement for operator , to be called. But if I change

    uninitialized_copy(X(a), X(a+10), X(b)); 

in the above code to

    copy(X(a), X(a+10), X(b)); 

then Hello world! is still printed ten times. The said results are observable in both, VS2005 and GCC 4.3.4. However, if I write

    mismatch(X(a), X(a+10), X(b)); 

instead, then VS2005 prints Hello world! ten times but GCC does not.

Unfortunately I couldn't find where the standard prohibits operator, overloading for iterator types. On the contrary, it prohibits the implementations to do calls as above [global.functions]:

Unless otherwise specified, global and non-member functions in the standard library shall not use functions from another namespace which are found through argument-dependent name lookup (3.4.2).

So who of the four parties is wrong: MSVC, GCC, ISO or me? (Choose one)

like image 637
Yakov Galka Avatar asked Jan 03 '12 22:01

Yakov Galka


People also ask

How to overload comma operator in c++?

In C++, we can overload the comma operator using Operator Overloading. For Example: For “Send the query X to the server Y and put the result in variable Z”, the “and” plays the role of the comma. The comma operator (, ) is used to isolate two or more expressions that are included where only one expression is expected.

What is the comma operator in C?

The comma operator in c comes with the lowest precedence in the C language. The comma operator is basically a binary operator that initially operates the first available operand, discards the obtained result from it, evaluates the operands present after this, and then returns the result/value accordingly.


1 Answers

Nice catch. I think in my humble opinion that the ISO committee's intention was that §3.4.2 should be followed. The suggested semantics of uninitialized_copy is wrongly interpreted as if requiring the comma to be called. And implementations should not be using it (I'd report a bug to gcc btw).

like image 65
Giovanni Funchal Avatar answered Oct 18 '22 14:10

Giovanni Funchal