2017-09-29 27 views
5

Tôi đang viết một số mã mà kiểu trả về của một hàm khá phức tạp. Tôi muốn sử dụng số auto để khấu trừ từ loại trả lại, nhưng điều đó rõ ràng là không thể trong một tờ khai chuyển tiếp. Vì vậy, tôi đã hy vọng ít nhất là chỉ lặp lại trong các nội dung của báo cáo kết quả lợi nhuận và làm như sau,Xung đột giữa loại trả về theo sau và khấu trừ loại trả về

int q = 5; // veeery complicated type 

/* Declaration - the best we can do */ 
auto f() -> decltype(q); 

/* Later, in a different file */  
auto f() { 
    return q; 
} 

này tạo ra các lỗi sau đây trong GCC 7,

error: ambiguating new declaration of ‘auto f()’ 
note: old declaration ‘int f()’ 

Dĩ nhiên tôi có thể lặp lại

auto f() -> decltype(q) { 
    return q; 
} 

trong định nghĩa (hoạt động) nhưng tại sao tôi cần phải khi loại trả lại được đưa ra duy nhất theo tuyên bố return? Làm thế nào là loại f trong định nghĩa của tôi cuối cùng bất kỳ mơ hồ hơn int f()?

+0

Không phải là một guru tiêu chuẩn, nhưng trình biên dịch phải làm nếu là những gì , theo định nghĩa thực tế của bạn về hàm, kiểu dấu và loại 'tự động' không khớp? Tôi nghĩ đó là lý do tại sao gcc báo cáo nó. – YiFei

+1

Tôi hy vọng nó chỉ đơn giản là cho tôi biết nó không phù hợp. Cho dù hai loại là giống nhau hay không phải là dễ dàng để trả lời. Nhưng bây giờ bạn đề cập đến điều này, khá thú vị là lỗi được tạo ra bởi 'int f(); long f() {return 1; } 'được diễn đạt theo cùng một cách! –

+0

Tôi đồng ý với bạn. Tôi cũng muốn biết là có bất kỳ tham chiếu chuẩn nào nêu rõ rằng một kiểu trả về 'auto'-deduced không thể được gấp lại với hàm trả về cụ thể (ngay cả khi chúng khớp). – YiFei

Trả lời

8

Vấn đề ở đây là trả về theo sau không giống với kiểu trả về thuần túy. Trong [dcl.spec.auto]/2

[...] Nếu chức năng declarator bao gồm một dấu-trở-type (8.3.5), chỉ định kiểu trả về tuyên bố của hàm

Vì vậy

auto f() -> decltype(q); 

thực sự là

int f(); 

đó là khác nhau từ

auto f() 

Ngoài ra còn có [dcl.spec.auto]/13

Redeclarations hoặc chuyên ngành của một hàm hoặc chức năng mẫu với một kiểu trả về tuyên bố rằng sử dụng một loại placeholder thì tùy theo tính cũng sử dụng trình giữ chỗ đó, không phải loại suy luận. [Ví dụ:

auto f(); 
auto f() { return 42; } // return type is int 
auto f();    // OK 
int f();     // error, cannot be overloaded with auto f() 
decltype(auto) f();  // error, auto and decltype(auto) don’t match 

Đó là loại trái ngược với những gì đang xảy ra ở đây nhưng nó tiếp tục minh hoạ cho rằng điều này là không được phép

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