2011-07-08 17 views
6

La función de plantilla iota se agregó a la biblioteca estándar para llenar un rango de iteradores con una secuencia de valores cada vez mayor.¿Por qué no agregaron una versión de operador de iota?

template<typename ForwardIterator, typename Tp> 
    void 
    iota(ForwardIterator first, ForwardIterator last, Tp value) 
    { 
     for (; first != last; ++first) 
     { 
      *first = value; 
      ++value; 
     } 
    } 

mayoría de las otras plantillas en <numeric> tienen versiones que aceptan los operadores especificados por el usuario. Tener esta :

template<typename ForwardIterator, typename Tp, typename Operator> 
    void 
    iota(ForwardIterator first, ForwardIterator last, Tp value, Operator op) 
    { 
     for (; first != last; ++first) 
     { 
      *first = value; 
      op(value); 
     } 
    } 

sería conveniente si usted no quiere (o no puede) operador de sobrecarga ++() para Tp. Me gustaría encontrar esta versión más ampliamente utilizable que el operador predeterminado ++() versión. <

+0

Tienes razón, con lambdas, la segunda versión no solo es más flexible que la primera, sino que es casi tan fácil de usar para incrementarla. –

Respuesta

4

Con lambdas, la segunda versión no ahorra mucho, solo puede usar std::generate.

template<typename ForwardIterator, typename Tp, typename Operator> 
void iota(ForwardIterator first, ForwardIterator last, Tp value, Operator op) 
{ 
    std::generate(first, last, [&value,&op](){auto v = value; op(value); return v;}); 
} 

De hecho, esto hace que la implementación existente de std::iota muy redundante:

template<typename ForwardIterator, typename Tp> 
void iota(ForwardIterator first, ForwardIterator last, Tp value) 
{ 
    std::generate(first, last, [&value](){return value++;}); 
} 
+0

Cierto, iota probablemente solo bendice la versión de SGI que es distribuida por gcc como una extensión y probablemente otras implementaciones. – emsr

+1

'partial_sum' es aún mejor (no' [&] '). 'vector i (10,0); partial_sum (i.begin(), i.end(), i.begin(), [] (int p, int c) {return p ++;} ' –

+0

@kirill: Casi así, pero' partial_sum' no acepta un parámetro 'value' para sembrar la acumulación. Además, el' ++ 'postincrement en su fragmento de código es inútil ... el valor actualizado de' p' se descarta inmediatamente. De hecho, su fragmento de código es totalmente incorrecto, y doesn ' t crear una secuencia creciente. –

5

Sospecho que la razón es la habitual mezcla de una o más de las siguientes razones:

  • Nadie envió una propuesta
  • No se consideró lo suficientemente importante para este versión (que ya era enorme , y muy tarde)
  • cayó por las grietas y fue olvidado (como copy_if en C++ 98)
  • es fácil de reemplazar el uso de std::generate.
Cuestiones relacionadas