2012-07-01 15 views
8

más al punto, lo que está mal con este código:el que los identificadores están disponibles para lambda en lista de inicialización del constructor

#include <assert.h> 
#include <functional> 
using namespace std; 

    template< class BaseObjectId > 
    class Check 
    { 
    protected: 
     Check(function<bool()> const f) { assert(f()); } 
    }; 

    template< int tpMinValue, int tpMaxValue > 
    class IntegerSubrange 
     : private Check< IntegerSubrange< tpMinValue, tpMaxValue > > 
    { 
    private: 
     int  value_; 

    public: 
     enum :int { minValue = tpMinValue, maxValue = tpMaxValue }; 

     static bool rangeContains(int const x) 
     { 
      return (minValue <= x && x <= maxValue); 
     } 

     operator int() const 
     { 
      return value_; 
     } 

     void operator/=(int const rhs) 
     { 
      value_ /= rhs; 
      assert(rangeContains(value_)); 
     } 

     explicit IntegerSubrange(int const value) 
      : Check< IntegerSubrange< tpMinValue, tpMaxValue > >(
       [=]() -> bool { return rangeContains(value); } 
       ) 
      , value_(value) 
     {} 
    }; 

int main() {} 

Visual C++ informa de un error sintaxis:

 
foo.cpp 
foo.cpp(41) : error C2059: syntax error : ')' 
     foo.cpp(44) : see reference to class template instantiation 'IntegerSubrange' being compiled 
foo.cpp(42) : error C2059: syntax error : ',' 
foo.cpp(43) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body 
+2

compila bien con g ++ 4.6.3 –

+0

ah, tengo que actualizar mi g ++ continuación. voy a comprobar con Visual C++ 11 también! ** Compila muy bien con Visual C++ 11 **, no lo hubiera creído –

+0

@Griwes: g ++ 4.6.3 es más nuevo que 4.6.1, y 4.6.1 compila lambdas muy bien. –

Respuesta

4

para resumir la comentarios: El código del interrogador es válido. Aparentemente, algunos compiladores anteriores a GCC 4.4 o Visual C++ 2011 lo rechazarán, debido al soporte incompleto de esos compiladores para las lambdas de C++ 11-style. Pero los compiladores modernos (y ciertamente cualquier compilador que afirme soportar el nuevo estándar C++ 11) deberían manejarlo bien.

Para responder a su pregunta, literalmente: En un ctor-inicializador lista, los mismos identificadores están disponibles (y se refieren a las mismas cosas), ya que se refieren a si los dos se movió dentro de las llaves de la función constructora sí mismo. En particular, esto significa que usted puede hacer

class C { 
    const char *p_ = "foo"; 
    char c_; 
    C(int): p_(__func__) { }  // referring to "__func__" 
    C(double): c_(*this->p_) { } // referring to "this" 
}; 

Esto es lo que la norma tiene que decir sobre el tema:

nombres de la lista de expresión o -init-lista arriostrados de a mem-initializer se evalúan en el ámbito del constructor para el que se ha especificado el mem-initializer. ... [Nota: Debido a que elmem-inicializador son [sic ] evaluado en el alcance del constructor, el puntero puede ser this utilizado en la lista de expresión de un mem-inicializador para hacer referencia al objeto que se está inicializando. - finales nota]     (N3337 §12.6.2 #12)

+0

Me alegra ayudar. A menudo busco preguntas interesantes sin respuesta, así que si veo una pregunta interesante que ha sido "respondida" en comentarios pero no en una "Respuesta" real, a menudo escribo una para sacarla de mis resultados de búsqueda. :) – Quuxplusone

Cuestiones relacionadas