2011-06-20 30 views
14

Chúng tôi không được phép định nghĩa một cấu trúc functor bên trong một hàm bởi vì một không được phép sử dụng các cấu trúc hàm đã khai báo trong sự khởi tạo của các mẫu hàm.Những hạn chế nào trong ISO C++ 03 trên các cấu trúc được xác định tại phạm vi chức năng?

Có bất kỳ cạm bẫy quan trọng nào khác cần lưu ý không? Ví dụ. điều này có thể là xấu:

int foo() 
{ 
    struct Scratch 
    { 
     int a, b, c; 
    }; 
    std::vector<Scratch> workingBuffer; 
    //Blah Blah 
} 
+1

@Nawaz: Đây không phải là bản sao chính xác Tôi nghĩ rằng –

+0

@ 0A0D: Loại câu hỏi được hỏi ở đây, cũng đã được trả lời trong chủ đề đó. Do đó một bản sao có thể. – Nawaz

+2

@Billy: Trong trường hợp đó, hãy để tôi sao chép dán câu trả lời của tôi từ chủ đề khác. – Nawaz

Trả lời

22

1. C++ chuẩn cấm sử dụng các lớp được xác định cục bộ với mẫu.

14.3.1/2: Một loại địa phương, một loại không có mối liên kết, một loại vô danh hoặc một loại phức tạp từ bất kỳ các loại sẽ không được sử dụng như một mẫu đối số cho một kiểu mẫu -tham số.

Một mã ví dụ:

template <class T> class X { /* ... */ }; 
    void f() 
    { 
     struct S { /* ... */ }; 
     X<S> x3; // error: local type used as 
       // template-argument 
     X<S*> x4; // error: pointer to local type 
       // used as template-argument 
    } 

Dưới đây là một chút tham khảo thêm tài liệu từ IBM:

2. Khai báo trong một lớp học địa phương chỉ có thể sử dụng tên loại, kiểu liệt kê, các biến tĩnh từ phạm vi kèm theo, cũng như các biến và hàm bên ngoài.

Một Mã số Ví dụ:

int x;       // global variable 
void f()      // function definition 
{ 
     static int y;   // static variable y can be used by 
           // local class 
     int x;     // auto variable x cannot be used by 
           // local class 
     extern int g();   // extern function g can be used by 
           // local class 

     class local    // local class 
     { 
      int g() { return x; }  // error, local variable x 
             // cannot be used by g 
      int h() { return y; }  // valid,static variable y 
      int k() { return ::x; } // valid, global x 
      int l() { return g(); } // valid, extern function g 
     }; 
} 

int main() 
{ 
     local* z;    // error: the class local is not visible 
     return 0; 
} 

3. Một lớp học tại địa phương không thể có tĩnh thành viên dữ liệu

Một Mã số Ví dụ:

void f() 
{ 
    class local 
    { 
     int f();    // error, local class has noninline 
          // member function 
     int g() {return 0;} // valid, inline member function 
     static int a;   // error, static is not allowed for 
          // local class 
     int b;    // valid, nonstatic variable 
    }; 
} 
+0

+1 cho tiêu chuẩn ref. Bất kỳ cạm bẫy nào khác cần lưu ý? –

0

Có. Không thể sử dụng các lớp địa phương làm thông số mẫu trong C++ 03

+0

Bạn có tài liệu tham khảo không? Tôi biết bạn không được phép sử dụng chúng cho việc khấu trừ đối số của các mẫu chức năng - nhưng không nhất thiết phải cho các lớp instantiation theo cách thủ công. –

1

Local struct/lớp không thể có thành viên dữ liệu tĩnh, chỉ s chức năng thành viên tatic. Ngoài ra, chúng không thể là mẫu.

2

Phạm vi của các lớp địa phương là hàm mà chúng được xác định. Nhưng điều đó không thú vị với chính nó .

Điều gì làm cho các lớp học địa phương thú vị là nếu họ thực hiện một số giao diện, sau đó bạn có thể tạo thể hiện của nó (sử dụng new) và trả lại, do đó làm cho thi truy cập thông qua cơ sở con trỏ lớp thậm chí bên ngoài hàm.

Một số thông tin khác về các lớp học tại địa phương:

  • Họ không thể xác định các biến thành viên tĩnh.

  • Chúng không thể truy cập các biến cục bộ "tự động" không có chức năng của hàm kèm theo. Nhưng họ có thể truy cập các biến số static.

  • Chúng có thể được sử dụng trong các chức năng mẫu. Tuy nhiên, chúng không thể được sử dụng làm đối số mẫu mẫu.

  • Nếu chúng được xác định bên trong chức năng mẫu, thì chúng có thể sử dụng các tham số mẫu của hàm kèm theo.

  • Lớp địa phương là cuối cùng, điều đó có nghĩa là người dùng bên ngoài hàm không thể lấy được từ lớp địa phương để hoạt động. Nếu không có các lớp địa phương, bạn phải thêm một không gian tên không tên trong đơn vị dịch riêng biệt.

  • Các lớp địa phương được sử dụng để tạo trampoline functions thường được gọi là thunks.

Một số tài liệu tham khảo từ các tiêu chuẩn (2003)

9,8 tờ khai lớp địa phương [class.local]

\ 1. Một lớp có thể được định nghĩa trong một định nghĩa hàm; một lớp học như vậy là được gọi là một lớp học địa phương. Tên của một lớp học địa phương là trong phạm vi kèm theo của nó. Lớp địa phương nằm trong phạm vi của phạm vi bao quanh và có các quyền truy cập cùng tên bên ngoài chức năng cũng như chức năng kèm theo . Các khai báo trong một lớp địa phương chỉ có thể sử dụng các tên kiểu, các biến số tĩnh, các biến ngoài và các hàm và các điều tra từ phạm vi bao gồm .

[Example: 

int x; 
void f() 
{ 
    static int s ; 
    int x; 
    extern int g(); 

    struct local { 
     int g() { return x; } // error: x is auto 
     int h() { return s; } // OK 
     int k() { return ::x; } // OK 
     int l() { return g(); } // OK 
    }; 
// ... 
} 
local* p = 0; // error: local not in scope 

—end example] 

\ 2. Một hàm kèm theo không có quyền truy cập đặc biệt vào các thành viên của lớp địa phương ; nó tuân thủ các quy tắc truy cập thông thường (khoản 11). Các hàm thành viên của một lớp học địa phương là sẽ được xác định trong phạm vi định nghĩa lớp học của chúng, nếu chúng là được xác định.

\ 3. Nếu lớp X là một lớp địa phương, một lớp lồng nhau Y có thể được khai báo trong lớp X và sau đó được định nghĩa trong định nghĩa của lớp X hoặc sau này là được định nghĩa trong cùng phạm vi với định nghĩa của lớp X. Lớp lồng nhau một lớp địa phương là một lớp địa phương.

\ 4. Một lớp địa phương sẽ không có các thành viên dữ liệu tĩnh.

0

cấu trúc cục bộ hoàn toàn hợp pháp, ngay cả trong C++ 98. Bạn không thể sử dụng chúng với các mẫu trong C++ 98, trong khi bạn có thể trong C++ 0x. g ++ 4.5 hỗ trợ sử dụng các cấu trúc cục bộ với các khuôn mẫu trong chế độ -std = C++ 0x.

+0

Tôi nghĩ ideone sử dụng c + + 0x 4.5, nhưng nó vẫn cung cấp lỗi cho địa chỉ 'template struct' http://www.ideone.com/5xhWE – iammilind

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