2017-06-03 16 views
13

Vì vậy, tôi có hàm có chữ ký cụ thể trong tệp tiêu đề và tôi muốn khai báo một hàm khác có cùng chữ ký bên trong một lớp mà không cần gõ các tham số một lần nữa, và dĩ nhiên, hy vọng không có macro ... Hàm thành viên cũng sẽ có một tham số ẩn thêm rõ ràng, con trỏ this (vì nó không phải là một hàm thành viên tĩnh).Sử dụng decltype để tự khai báo toàn bộ loại hàm (không phải con trỏ!)

Bây giờ, tôi thực sự ngạc nhiên khi hack/trick sau đây hoạt động trong cả GCC và ICC, nhưng tôi không chắc liệu đó là "hợp pháp" C++ hay không. Tôi không đặc biệt quan tâm đến tính hợp pháp nếu đó là tiện ích được hỗ trợ, nhưng tiếc là tôi không muốn nó phá vỡ bản cập nhật phiên bản trình biên dịch vì một số người đã quyết định tùy ý chặn tính năng hữu ích này vì tiêu chuẩn nói "không" (loại công cụ đó thực sự làm phiền tôi thành thật).

Đây là những gì tôi muốn nói:

// test.hpp 
int func(int x) { return x; } 

struct foo 
{ 
    decltype(func) fn; // <-- legal? 
}; 

int test() 
{ 
    return foo().fn(6); 
} 


// then in test.cpp 
int foo::fn(int x) { return x + 42; } 

này công trình (với GCC và ICC), nhưng tôi không biết nếu đó là "hợp pháp" trong tiêu chuẩn. Tôi yêu cầu chỉ được đảm bảo rằng nó là hợp pháp và nó sẽ không đột ngột ngừng làm việc trong tương lai.

(nếu đó là không hợp pháp và bạn muốn báo cáo nó như là một lỗi, xin vui lòng đánh dấu nó như là một gợi ý để làm cho nó một phần mở rộng trình biên dịch pháp lý thay vì giết chết nó ...)

Về cơ bản, nó giống như khai báo int fn(int x); trong cấu trúc, và đó là cách nó hoạt động hiện tại.

Nếu bạn hỏi tôi về trường hợp sử dụng: đó là khai báo hàm thành viên của trình bao cho chức năng miễn phí khác thực hiện điều gì đó với con trỏ this trước khi chuyển sang hàm miễn phí. Các thông số của nó phải khớp chính xác, rõ ràng. Một lần nữa, tôi không muốn gõ lại các tham số.

+3

Đó là hợp pháp miễn là không phải là loại phụ thuộc trong mẫu lớp học. –

+1

Để lạm dụng thêm, bạn có thể "khởi tạo" nó bằng "= 0;" và làm cho nó ảo –

+0

@ JohannesSchaub-litb Thú vị, và tắt chủ đề, nhưng tò mò: những gì hiện khởi tạo nó với 0 làm gì? Tôi chỉ biết bạn có thể "khởi tạo" nó với = xóa. – kktsuri

Trả lời

4

Điều đó có vẻ hợp pháp; nhưng ở định nghĩa bạn phải gõ lại. Cân nhắc sử dụng chuyển tiếp hoàn hảo để thay thế.

+0

Bạn nói đúng, nhưng làm thế nào tôi có thể sử dụng chuyển tiếp hoàn hảo khi nó được định nghĩa trong một đơn vị dịch khác (tệp cpp)? Tôi có nghĩa là tôi có thể làm cho nó "extern mẫu" (hoặc chỉ để lại nó không xác định) trong tập tin tiêu đề (tuyên bố), nhưng sẽ không instantiating là một vấn đề? Bạn có thể cung cấp một ví dụ mà không cần phải gõ nó (tốt, gõ lại hàm miễn phí 'func' là tốt, rõ ràng). Có lẽ tôi chỉ nhìn cái gì đó đơn giản. – kktsuri

+0

Dù sao, tôi sẽ chấp nhận câu trả lời của bạn vì câu trả lời cho câu hỏi, nhưng sẽ tốt hơn nếu bạn biết về chuyển tiếp hoàn hảo với một đơn vị dịch khác (các chức năng thực tế có hoạt động phức tạp hơn và tôi muốn giữ chúng ở một nơi) với LTO, họ sẽ được inline ngay cả trên các đơn vị dịch). Cảm ơn – kktsuri

+0

Điều gì khiến tôi kỳ quặc là loại 'fn' và' func' không giống 'static_assert (std :: is_same {}," ") 'Tôi thấy nó hoạt động hợp pháp như thế nào OP có nó, nhưng cũng có thể tưởng tượng' decltype' không được phép ở đây vì 'fn' không thuộc kiểu' int (int) ' –

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