2017-07-12 16 views
7

Tôi thấy hành vi khá lạ từ quan điểm của tôi: đối số mặc định chức năng không thể được chuyển tiếp trong mã dưới đây.Tại sao các tham số mặc định của hàm không thể được chuyển tiếp trong C++?

void Test(int test = int{}) {} 

template<typename F, typename ...Args> 
void Foo(F&& f, Args&&... args) 
{ 
    std::forward<F>(f)(std::forward<Args>(args)...); 
} 

int main() 
{ 
    Foo(Test, 0); // This compiles 
    Foo(Test); // This doesn't compile 
} 

Clang báo cáo: lỗi: quá ít đối số để gọi chức năng, dự kiến ​​1, có 0 GCC và báo cáo VC cùng lỗi.

Ai đó có thể giải thích được không?

Mã là ở đây: http://rextester.com/live/JOCY22484

+0

ngắn thử nghiệm: 'auto f = Kiểm tra; f(); ' – 0x499602D2

Trả lời

11

Test là một chức năng mà luôn có một cuộc tranh cãi. Nếu khai báo của nó với đối số mặc định có thể nhìn thấy khi Test được gọi theo tên, trình biên dịch sẽ ngầm thêm đối số mặc định vào cuộc gọi. Tuy nhiên, khi Test đã được chuyển đổi thành con trỏ hoặc tham chiếu đến hàm, thông tin đối số mặc định sẽ không còn hiển thị nữa.

này có thể được giải quyết bằng cách tạo ra một functor mà thực sự không mất không hoặc một lập luận và có những thông tin được mã hóa vào loại của nó vì vậy nó không thể bị phá hủy, như vậy:

trường hợp
struct Test { 
    void operator()(int) { /* ... */ } 
    void operator()() { operator(int{}); } 
} test; 
// ... 
Foo(test, 0); // ok 
Foo(test); // ok 
+4

' toán tử void() (int = 0) {/ * ... * /} 'sẽ hoạt động tốt. –

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