Làm cách nào để khởi tạo một cách rõ ràng một hàm mẫu?


117

Tôi có một hàm mẫu với một đối số. Tôi phải khởi tạo hàm đó mà không gọi hàm đó có nghĩa là tôi phải khởi tạo một cách rõ ràng.

Tôi có chức năng này:

template <class T> int function_name(T a) {}

Tôi đã khởi tạo chức năng đó như thế này:

template int function_name<int>(int);

Nhưng tôi gặp các lỗi sau:

error: expected primary-expression before 'template'
error: expected `;' before 'template'

Câu trả lời:


182

[CHỈNH SỬA 2]: Lưu ý rằng có một số nhầm lẫn về mã trong câu hỏi ban đầu do vấn đề định dạng mã. Xem câu trả lời của AnthonyHatchkins để biết thêm chi tiết.

Nếu bạn thực sự muốn khởi tạo (thay vì chuyên môn hóa hoặc một cái gì đó) hàm, hãy làm như sau:

template <typename T> void func(T param) {} // definition

template void func<int>(int param); // explicit instantiation.

[EDIT] Dường như có (rất nhiều) nhầm lẫn liên quan đến việc khởi tạo và chuyên môn hóa rõ ràng. Đoạn mã mà tôi đã đăng ở trên đề cập đến việc thuyết minh rõ ràng . Cú pháp cho chuyên môn hóa là khác nhau. Đây là cú pháp cho chuyên ngành:

template <typename T> void func(T param) {} // definition

template <> void func<int>(int param) {} // specialization

Lưu ý rằng dấu ngoặc nhọn sau khuôn mẫu!


3
đó là khởi tạo hay chuyên môn hóa ?
Nawaz

5
Không đúng. Bạn có thể yêu cầu trình biên dịch khởi tạo các mẫu một cách rõ ràng. Google cho "Trình tạo mẫu rõ ràng C ++" để biết thêm chi tiết.
hrnt

8
@Nawaz: bạn nhầm rồi. Tất nhiên nó luôn luôn là trình biên dịch khởi tạo, dòng đó là một yêu cầu từ người lập trình đến trình biên dịch để khởi tạo mẫu. Nếu bạn có bản sao của tiêu chuẩn C ++, hãy đọc 14.7.2 Thuyết minh rõ ràng
David Rodríguez - dribeas

16
Chuyên môn hóa có nghĩa là bạn có thể đang thay đổi cách triển khai của nó. Thuyết minh chỉ đơn giản có nghĩa là bạn đang gán nó cho một đơn vị biên dịch cụ thể, có thể lấy địa chỉ duy nhất của nó hoặc làm cho nó có sẵn như một chức năng thư viện hoặc để giảm sự cồng kềnh.
CashCow

3
@hrnt: Tôi nghĩ, bạn nói đúng. @Ashot: Tôi chỉ nhận thấy rằng cú pháp không có template<>dạng. Những gì anh ấy đã viết khác với chuyên môn hóa . +1 vì đã dạy tôi điều mới này. Tôi đang xóa bài đăng của mình. : D
Nawaz

20

Mã của bạn là chính xác.

Thông báo lỗi liên quan đến một vị trí trong mã mà bạn không trích dẫn ở đây.

Cập nhật:

Mã ban đầu là

template <class T> int function_name(T a) {}
template int function_name<int>(int);

và nó đã chính xác.

Nhưng nó không được trích dẫn và do đó trông như thế này:

template int function_name(T a) {}
template int function_name(int);

Nó tạo ra lỗi sau

a.cpp:1: error: explicit instantiation of non-template int function_name
a.cpp:1: error: expected `;' before ‘(’ token
a.cpp:3: error: function_name is not a template function

mà rõ ràng là khác với những gì OP đã trích dẫn.

Trong biến thể này, dòng thứ hai là ok ( <int>có thể được bỏ qua ở đây), nhưng dòng đầu tiên bị lỗi. Trình biên dịch không thể đoán đó Tlà một tham số mẫu.


Về mặt kỹ thuật, nó không phải là mã của anh ấy, nó là do Bill chỉnh sửa :) Mã gốc là template int function_name( T a) { }template int function_name(int);
hrnt

@hrnt Mã gốc không được định dạng đúng, nhưng nó đúng. Nếu tôi là Balaji, tôi sẽ quay lại và chấp nhận câu trả lời của bạn nếu anh ấy coi nó là hữu ích, nhưng đối với tôi (và có lẽ là cho bất kỳ ai khác) câu trả lời của bạn (mặc dù bản thân nó hoàn toàn đúng) lại không trả lời câu hỏi.
Antony Hatchkins

@hrnt Bạn nói đúng rằng mã gốc trông như vậy. Nhưng vì đối số mẫu suy ra nó vẫn hoạt động. Tôi phải đồng ý với Antony Hatchkins rằng lỗi phát sinh từ đoạn mã mà OP đã không trích dẫn, tuy nhiên tôi nghĩ câu trả lời của bạn vẫn hữu ích cho những người không biết về thuyết minh rõ ràng.
mpark

Vâng, hãy lấy tôi làm ví dụ. Tôi đã truy cập trang này khi tôi muốn cập nhật lại kiến ​​thức đã bị lãng quên của mình về tính năng thuyết minh rõ ràng - và nó không giúp được gì nhiều cho tôi. Riêng tôi, không có gì nhầm lẫn về cú pháp. Điều gì có thể gây nhầm lẫn về instantiation rõ ràng là sử dụng của nó
Antony Hatchkins

@AntonyHatchkins À, đúng - Tôi không xem nguồn gốc của câu hỏi ban đầu, chỉ là cách nó xuất hiện trên màn hình của tôi. Tôi sẽ +1 câu trả lời này và sửa đổi câu trả lời ban đầu của tôi để lưu ý sự nhầm lẫn liên quan đến câu hỏi ban đầu.
giờ
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.