2012-07-01 29 views
8

hơn vào vấn đề, có gì sai với mã này:mà định danh có sẵn để lambda trong constructor danh sách initializer

#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++ báo cáo một lỗi cú pháp:

 
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

Biên dịch tốt với g ++ 4.6.3 –

+0

ah, tôi cần phải cập nhật g của tôi ++ sau đó. tôi cũng sẽ kiểm tra bằng C++ 11 trực quan! ** Nó biên dịch tốt với Visual C++ 11 **, tôi sẽ không tin nó –

+0

@Griwes: g ++ 4.6.3 mới hơn 4.6.1 và 4.6.1 biên dịch lambdas tốt. –

Trả lời

4

Để tóm tắt comments: Mã của người hỏi có giá trị. Rõ ràng một số trình biên dịch cũ hơn GCC 4.4 hoặc Visual C++ 2011 sẽ từ chối nó, do những trình biên dịch không hỗ trợ đầy đủ cho lambda C++ 11 kiểu. Nhưng các trình biên dịch hiện đại (và chắc chắn là bất kỳ trình biên dịch nào yêu cầu hỗ trợ chuẩn C++ 11 mới) đều phải xử lý nó tốt.

Để trả lời câu hỏi của bạn theo nghĩa đen: Trong một danh sách ctor-initializer-, cùng một số nhận dạng có sẵn (và tham khảo cùng một thứ) như chúng sẽ đề cập đến nếu bạn di chuyển chúng bên trong dấu ngoặc nhọn của hàm tạo chinh no. Đặc biệt, điều này có nghĩa rằng bạn có thể làm

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

Dưới đây là những gì các tiêu chuẩn có nói về đề tài này:

Names trong biểu-list hoặc chuẩn bị tinh thần-init-list của a Bộ khởi tạo mem được đánh giá trong phạm vi của hàm tạo mà trong đó bộ khởi tạo mem được chỉ định. ... [Lưu ý:mem-initializer là [sic] đánh giá trong phạm vi của các nhà xây dựng, con trỏ this có thể sử dụng trong biểu-list của một mem-initializer để tham chiếu đến đối tượng đang được khởi tạo. - cuối note]     (N3337 §12.6.2 #12)

+0

Rất vui được giúp đỡ. Tôi thường trawl cho câu hỏi chưa được trả lời thú vị, vì vậy nếu tôi nhìn thấy một câu hỏi thú vị đó là "trả lời" trong ý kiến ​​nhưng không phải trong một "Trả lời" thực sự, tôi sẽ thường viết một lên chỉ để có được nó ra khỏi kết quả tìm kiếm của tôi. :) – Quuxplusone

Các vấn đề liên quan