2011-01-01 35 views
10

Tiêu đề này là khá tự giải thích, nhưng đây là một ví dụ đơn giản:Chúng tôi có thể có cấu trúc ẩn danh làm đối số mẫu không?

#include <cstdio> 

template <typename T> 
struct MyTemplate { 

    T member; 

    void printMemberSize() { 
     printf("%i\n", sizeof(T)); 
    } 

}; 

int main() { 

    MyTemplate<struct { int a; int b; }> t; // <-- compiler doesn't like this 

    t.printMemberSize(); 

    return 0; 

} 

Trình biên dịch phàn nàn khi tôi cố gắng sử dụng một cấu trúc mang tính chất như một mẫu đối số. Cách tốt nhất để đạt được một cái gì đó như thế này mà không cần phải có một định nghĩa struct, được đặt tên riêng biệt là gì?

Trả lời

7

Bạn không được phép xác định một loại vô danh như một mẫu đối số trong C++ 03 hoặc thậm chí trong C++ 0x.

Điều tốt nhất bạn có thể làm điều đó để tạo ra một địa phương tên là struct to main (trong C++ 0x)

1: Bạn không được phép sử dụng một loại địa phương như mẫu đối số trong C + +03, tuy nhiên C++ 0x cho phép nó.

Ngoài ra, hãy xem Báo cáo lỗi here. Các giải pháp đề xuất đề cập

Các loại sau đây không được sử dụng như một mẫu đối số cho một mẫu kiểu tham số:

  • một loại có tên không có mối liên hệ
  • một lớp vô danh hoặc kiểu liệt kê không có tên cho mục đích liên kết (7.1.3 [dcl.typedef])
  • một phiên bản cv-trình độ của một trong các loại trong danh sách này
  • một loại tạo bởi ứng dụng của các nhà khai thác declarator đến một trong các loại trong danh sách này
  • một loại chức năng có sử dụng một trong những loại trong danh sách này

Trình biên dịch phàn nàn khi tôi cố gắng sử dụng một cấu trúc mang tính chất như một tham số mẫu.

Ý của bạn có phải là đối số mẫu không? Thông số mẫu khác với đối số mẫu.

Ví dụ

template < typename T > // T is template parameter 
class demo {}; 

int main() 
{ 
    demo <int> x; // int is template argument 
} 
+0

Trong C++ 0x, một đối tượng của một kiểu chưa đặt tên có thể được suy luận như một đối số mẫu, nhưng tôi không nghĩ một loại chưa đặt tên có thể được chỉ định rõ ràng trong danh sách đối số mẫu. –

+0

Prasoon, bạn có thể giới thiệu cho tôi phần đúng của tiêu chuẩn không? Trường hợp thử nghiệm của tôi với một cấu trúc chưa đặt tên (được truyền cho typedef, nhưng tất cả chúng ta đều biết rằng một tên typedef không phải là một tên struct) biên dịch tốt. –

+0

@Ben: '14.3.1/2' –

4

Vấn đề của bạn không phải là cấu trúc không được đặt tên, đó là cấu trúc được khai báo cục bộ. Sử dụng kiểu cục bộ làm đối số mẫu không được phép trong C++ 03. Nó sẽ được trong C + + 0x mặc dù, vì vậy bạn có thể thử nâng cấp trình biên dịch của bạn.

EDIT: Trên thực tế, vấn đề của bạn là bên trong danh sách đối số mẫu không phải là nơi hợp pháp để đặt định nghĩa lớp, có hoặc không có tên, theo tiêu chuẩn C++.

litb chỉ ra rằng mặc dù nó phù hợp với ngữ pháp C++ 0x, việc xác định một loại ở đây bị cấm bởi [dcl.type]:

Một loại-Speci fi er-seq thì không de fi ne một lớp hoặc liệt kê trừ khi nó xuất hiện trong loại-id của một khai báo bí danh (7.1.3) mà không phải là khai báo của một khai báo mẫu.

simple-template-id: 
    template-name < template-argument-list_opt > 

template-argument-list: 
    template-argument ..._opt 
    template-argument-list , template-argument ..._opt 

template-argument: 
    constant-expression 
    type-id 
    id-expression 

type-id: 
    type-specifier-seq abstract-declarator_opt 

type-specifier-seq: 
    type-specifier attribute-specifier-seq_opt 
    type-specifier type-specifier-seq 

type-specifier: 
    trailing-type-specifier 
    class-specifier 
    enum-specifier 

class-specifier: 
    class-head { member-specification_opt } 

Trong một thời gian tôi đã có một câu hỏi về typedef tên, nhưng litb xóa mà lên. Họ được phép như các đối số mẫu qua:

trailing-type-specifier: 
    simple-type-specifier 
    elaborated-type-specifier 
    typename-specifier 
    cv-qualifier 

simple-type-specifier: 
    :: opt nested-name-specifier_opt type-name 
    :: opt nested-name-specifier template simple-template-id 
    char 
    char16_t 
    char32_t 
    wchar_t 
    bool 
    short 
    int 
    long 
    signed 
    unsigned 
    float 
    double 
    void 
    auto 
    decltype-specifier 

type-name: 
    class-name 
    enum-name 
    typedef-name 
    simple-template-id 
+0

Thật sự tôi đang sử dụng C++ 0x khả năng GCC 4.5 của. Tính năng này chưa được triển khai chưa? – nonoitall

+0

@nonoitall: [C++ tag wiki 0x] (http://stackoverflow.com/tags/c%2b%2b0x/info) có liên kết đến nhiều thông tin về trạng thái của hỗ trợ C++ 0x trong một số trình biên dịch . Nó nói rằng nó được cho là được thêm vào trong gcc 4.5. [Ghi chú phát hành gcc chính thức] (http://gcc.gnu.org/gcc-4.5/changes.html) nói "Trong chế độ C++ 0x, các lớp địa phương và ẩn danh hiện được phép làm đối số mẫu". Bạn đang biên dịch với tùy chọn '-std = gnu ++ 0x', đúng không? –

+0

Tệ của tôi. Rõ ràng đây là thứ bị bỏ lại phía sau cổng GG 4.5 của MinGW. Đã cố gắng biên dịch nó trên một hộp Linux và nó sẽ biên dịch khi sử dụng một cấu trúc được định nghĩa cục bộ (mặc dù sử dụng một cấu trúc ẩn danh như một đối số vẫn sẽ không bay)./Tôi đi để cài đặt Cygwin. – nonoitall

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