Đối số mặc định của mẫu


151

Nếu tôi được phép làm như sau:

template <typename T = int>
class Foo{
};

Tại sao tôi không được phép làm như sau?

Foo me;

Nhưng tôi phải xác định như sau:

Foo<int> me;

C ++ 11 đã giới thiệu các đối số mẫu mặc định và ngay bây giờ chúng khó nắm bắt được sự hiểu biết hoàn chỉnh của tôi.

Câu trả lời:


188

Bạn phải làm:

Foo<> me;

Các đối số mẫu phải có mặt nhưng bạn có thể để trống.

Hãy nghĩ về nó giống như một hàm foovới một đối số mặc định duy nhất. Biểu thức foosẽ không gọi nó, nhưng foo()sẽ. Cú pháp đối số vẫn phải ở đó. Điều này phù hợp với điều đó.


4
@Pubby Tôi cho rằng nó sẽ tạo ra một số biến chứng không cần thiết nếu Foo có thể là định danh mẫu hoặc có thể là một khởi tạo rõ ràng tùy thuộc vào việc có một đối số mặc định hay không. Tốt hơn nên giữ cú pháp khởi tạo rõ ràng. Hãy nghĩ về nó giống như một hàm foovới một tham số mặc định duy nhất. Bạn không thể gọi nó như thế foo, bạn gọi nó với foo(). Nó có ý nghĩa để giữ sự nhất quán này.
Joseph Mansfield

2
@sftrabbit nhưng bạn không thể gọi một hàm không có đối số như foomột trong hai; bạn có thể đặt tên cho một lớp không có đối số Foo.
Seth Carnegie

4
@aschepler Với một hàm, các đối số mẫu có thể được suy ra từ các đối số hàm. Với một lớp, bạn không thể quyết định, cho dù bạn có nghĩa là một lớp mẫu với các đối số mặc định hay một lớp không phải là mẫu.
Olaf Dietsche

21
@OlafDietsche nhưng bạn không thể có một lớp mẫu và một lớp không phải mẫu có cùng tên, vì vậy trình biên dịch sẽ có thể quyết định bằng cách chỉ nhìn vào tên đó là gì.
Seth Carnegie

7
@Pubby Ủy ban tiêu chuẩn tự hỏi mình như vậy, tôi đoán vậy. Bây giờ, với C ++ 17, <>không còn cần thiết trong trường hợp này. Kiểm tra câu trả lời của tôi để biết thêm chi tiết.
Paolo M

53

Với C ++ 17, bạn thực sự có thể.

Tính năng này được gọi là khấu trừ đối số mẫu lớp và thêm linh hoạt hơn vào cách bạn có thể khai báo các biến của các kiểu templated .

Vì thế,

template <typename T = int>
class Foo{};

int main() {
    Foo f;
}

hiện là mã C ++ hợp pháp .


5
Lạ thật. Chỉ cần thử nó trong dự án C ++ 17 của tôi và nó không hoạt động: "loại giữ chỗ mẫu 'const MyType' phải được theo sau bởi một id khai báo đơn giản". Tôi đang sử dụng GCC 7.3.0.
Silicomancer

1
@Silicomancer Thật khó để nói mà không nhìn thấy mã và dòng lệnh của bạn ... Có lẽ bạn đang xử lý các con trỏ như ở đây ?
Paolo M

1
Clang không chấp nhận nó có vẻ? coliru.stacked-crooking.com/a/c5d3c0f90ed263c2
Người đứng đầu

1
@Borgleader Rõ ràng, Coliru đang sử dụng clang 5.0. Đánh giá bằng cách này , nó sẽ hỗ trợ khấu trừ đối số mẫu C ++ 17, nhưng rõ ràng id không. Nếu bạn thử ví dụ tương tự của bạn trong Wandbox bằng clang 7.0, nó hoạt động hoàn hảo.
Paolo M

2
@PaoloM Thật tuyệt, thật vui khi biết đây chỉ là một vấn đề về phiên bản trình biên dịch. Cảm ơn đã xem xét này.
Người đứng đầu

19

Bạn không được phép làm điều đó nhưng bạn có thể làm điều này

typedef Foo<> Fooo;

và sau đó làm

Fooo me;

Có sự khác biệt nào trong điều này với loại mặc định và : typedef Foo<float> Fooo;, không có loại mặc định?
qrikko

5
Cách nói của C ++ 11 sẽ là nóiusing Fooo = Foo<>;
Adrian W

18

Bạn có thể sử dụng như sau:

Foo<> me;

Và có intđược đối số mẫu của bạn. Các dấu ngoặc nhọn là cần thiết và không thể bỏ qua.


Có ý nghĩa và cảm ơn bạn, nhưng, như đã lưu ý dưới đây, tại sao loại chỉ định lại có mặt?
dùng633658

@ user633658: Ý của bạn là "specifier"? Tôi không chắc là tôi hiểu
Andy Prowl

Dù sao, liên quan đến lý do đằng sau sự cần thiết của dấu ngoặc góc trống rỗng, tôi chỉ có thể đưa ra phỏng đoán và tất cả họ đều loại trừ sự mơ hồ có thể xảy ra với việc sử dụng tên của mẫu, nhưng tôi phải thú nhận rằng tôi không biết chính xác lý do
Andy Prowl

Tôi hoàn toàn nghi ngờ yêu cầu đối với <> là cho phép trình phân tích cú pháp của trình biên dịch xác định rằng bạn đang đề cập đến một lớp templated gọi là foo, chứ không phải là một thứ khác gọi là foo.
Mac
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.