c++ language-lawyer comma-operator

c++ - ¿Debería la implementación protegerse contra la sobrecarga de comas?



language-lawyer comma-operator (1)

Por ejemplo, uninitialized_copy se define en el estándar como:

Efectos:

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

Si se entiende literalmente, este es un requisito para llamar al operator ,(ForwardIterator, InputIterator) . Y de hecho este código imprime Hello world! diez veces:

#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)); }

Sin embargo, para la mayoría de los otros algoritmos, el estándar proporciona la descripción en prosa. Por ejemplo, para la copy no hay ningún requisito para el operador , para ser llamado. Pero si me cambio

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

en el código anterior a

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

entonces Hello world! Todavía se imprime diez veces . Dichos resultados son observables tanto en VS2005 como en GCC 4.3.4. Sin embargo, si escribo

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

En su lugar, entonces VS2005 imprime Hello world! Diez veces, pero GCC no lo hace.

Desafortunadamente, no pude encontrar dónde el estándar prohíbe el operator, sobrecarga para los tipos de iteradores. Por el contrario, prohíbe que las implementaciones realicen llamadas como en [funciones globales]:

A menos que se especifique lo contrario, las funciones globales y no miembros de la biblioteca estándar no usarán funciones de otro espacio de nombres que se encuentren a través de la búsqueda de nombres dependiente del argumento (3.4.2).

Entonces, ¿quién de las cuatro partes está equivocado: MSVC, GCC, ISO o yo? (Elige uno)


Buena atrapada. Creo que, en mi humilde opinión, la intención del comité de ISO era que se siguiera el §3.4.2. La semántica sugerida de uninitialized_copy se interpreta erróneamente como si requiriera que se llame a la coma. Y las implementaciones no deberían usarlo (informaría un error a gcc por cierto).