2012-07-01 3 views
8

больше до точки, что не так с этим кодом:, какие идентификаторы доступны для лямбда в списке инициализации конструктора

#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++ сообщает об ошибке в синтаксиса:

 
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

компилирует хорошо с г ++ 4.6.3 –

+0

ах, мне нужно обновить г ++ то. Я также проверю с помощью Visual C++ 11! ** Он компилируется с Visual C++ 11 **, я бы не поверил –

+0

@Griwes: g ++ 4.6.3 новее 4.6.1, а 4.6.1 компилирует lambdas просто отлично. –

ответ

4

суммировать комментарии: Код опроса действителен. По-видимому, некоторые компиляторы старше GCC 4.4 или Visual C++ 2011 отклонят его из-за неполной поддержки компиляторов для lambdas в стиле 11 C++. Но современные компиляторы (и, конечно же, любой компилятор, претендующий на поддержку нового стандарта C++ 11) должны справиться с этим просто отлично.

Чтобы ответить на ваш вопрос буквально: В CTOR-инициализатор-листе, одни и те же идентификаторы доступны (и относится к тем же вещам), как они будут относиться к тому, если вы переместили их в фигурных скобках функции конструктора сам. В частности, это означает, что вы можете сделать

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

Вот что стандарт должен сказать по этой теме:

Имен в список_выражениях или приготовились-INIT-лист из a mem-initializer оцениваются в рамках конструктора, для которого задан флаг-инициализатор . ... [Примечания: Поскольку мем-инициализатор являются [так] оценивал в рамках конструктора this указателя может быть использован в список_выражениях из в MEM-инициализаторе для ссылки на инициализированный объект . - конец примечание]     (N3337 §12.6.2 #12)

+0

Рад помочь. Я часто травляю интересные интересующие вопросы, поэтому, если я вижу интересный вопрос, который был «дан» в комментариях, но не в реальном «ответе», я часто пишу его, чтобы вывести его из результатов поиска. :) – Quuxplusone

Смежные вопросы