2016-07-23 12 views
34

Tôi đã bắt đầu một dự án riêng tư mới và quyết định sử dụng thêm C++11/14 lần này. Vì vậy, tôi cũng bắt đầu sử dụng cú pháp trở lại mớiCú pháp trả về C++ mới có hạn chế không?

auto functionName() -> returnType; 

Nó hoạt động cho hầu hết các phần rất tốt, nhưng bây giờ tôi cần một số xử lý lỗi và không thể tìm ra cách để re-write thứ như thế này:

virtual const char* what() const noexcept override; 

với cú pháp mới. Có một số trường hợp không thể sử dụng cú pháp mới hoặc tôi không đủ thông minh để tìm đúng thứ tự? Đối với tôi, điều quan trọng là giữ cho mọi thứ nhất quán, vì vậy tôi hy vọng vấn đề là nhiều hơn về phía tôi.

+0

cho noexcept thấy ở đây: http://stackoverflow.com/questions/16598320/trailing-return-type-syntax-fails-with-noexcept-specifier –

+14

Kiểu trả về điều mới thực sự là một hack để cho phép việc sử dụng decltype() trên các tham số hàm. Vì các tham số hàm chỉ có thể được sử dụng trong decltype _after_ chúng đã được khai báo, nên một cấu trúc như vậy không thể được đặt ở vị trí 'cũ' cho kiểu trả về - vì vậy chúng di chuyển kiểu trả về xung quanh. Theo tôi, điều này đang giúp các nhà biên dịch biên dịch quá nhiều với chi phí làm cho toàn bộ ngôn ngữ trở nên vô dụng đối với mọi người khác. Ở mức độ nào, không có lý do ý thức hệ để bạn chuyển đổi toàn bộ dự án sang cú pháp 'mới'; nó vốn không tốt hơn hoặc hiện đại hơn. –

+4

Tôi không biết bất kỳ lý do nào để sử dụng cú pháp kiểu trả về theo đuôi trong mã không chung, trừ khi bạn cho rằng nó trông đẹp hơn. Có một số tính năng C++ 11 như 'tự động' hoặc khởi tạo cú đúp được cho là được sử dụng" theo mặc định "trong tất cả mã" hiện đại ", nhưng tôi chắc chắn các kiểu trả về chỉ tồn tại để hỗ trợ một tập con nhất định typesafe generic code mà không thể viết trước đó. – Ixrec

Trả lời

34

Vâng, đây không phải là điều bạn thường đoán.

virtual auto what() const noexcept -> const char * override; 

Đây chỉ là thứ tự bạn phải sử dụng. Cú pháp có thể khác, có lẽ, nhưng đây là những gì chúng ta có.

+13

Ugh. Và tại sao bất cứ ai nghĩ rằng điều này là cấp trên? Nó chắc chắn không dễ đọc hơn. Ký hiệu này chỉ nên được sử dụng trong các trường hợp hạn chế như đối với các mẫu mà nó thực sự cần thiết. –

+1

Tại sao cú pháp phải khác? Cú pháp mới sẽ trì hoãn kiểu trả về *, không phải là các vòng loại hoặc các thứ khác ... "ảo", "const", "ghi đè" và "noexcept" không phải là một phần của kiểu trả về để chúng ở lại vị trí của chúng. – gigabytes

+5

@CodyGray Không ai có thể nói rằng cú pháp mới là sạch hơn ở đây. Tôi khuyên bạn không nên sử dụng nó trong trường hợp này. Nó được giới thiệu cho mã chung, nơi bạn cần có các tham số hàm kiểu trong phạm vi để tạo kiểu trả về. Nó không phải là một lý do thẩm mỹ. Ah, và đối với lambdas, tất nhiên ... – gigabytes

21

Cú pháp mới hỗ trợ mọi cú pháp cũ.

virtual const char* what() const noexcept override; 

phải được viết lại như

virtual auto what() const noexcept -> const char * override; 

Trên thực tế, cú pháp mới hỗ trợ tính năng thậm chí nhiều hơn:

  • Nó cho phép bạn làm decltype trên đối số chức năng.

    template <typename A, typename B> auto plus(A a, B b) -> decltype(a+b) 
    { 
        return A + B; 
    } 
    
  • Nó cũng cho phép bạn làm decltype trên this, do đó cho phép bạn làm decltype trên hàm thành viên. See this.

    struct S 
    { 
        int a() {return 1;} 
        auto b() -> decltype(a()) {return 2;} // Works. 
        decltype(a()) c() {return 2;} // ERROR. 
    }; 
    

Nhưng trong khi cú pháp mới có tất cả những tính năng bổ sung, nó không phải là một sự thay thế cho cái cũ. Ít nhất đây là cách tôi hiểu nó.

Một số lập trình viên thích sử dụng nó, nhưng theo như tôi biết hầu hết các lập trình viên ở đây trên Stack   Tràn thích sử dụng cú pháp cũ khi có thể.

+5

Và đặc biệt là kiểu trả về cho phép bạn sử dụng một kiểu được định nghĩa trong lớp, không đủ điều kiện trong kiểu trả về. –

36

Lý do cho sự cố là noexcept là một phần của trình khai báo hàm (và được đề xuất là một phần của kiểu hàm trong C++ 17), trong khi override là một định danh (tùy chọn được sử dụng) không phải là một phần của khai báo hàm.

Do đó, mà không cần sử dụng override tuyên bố sẽ

virtual auto what() const noexcept -> const char *; 

và, vì override phải xuất hiện sau tuyên bố này, nó sẽ gây ra

virtual auto what() const noexcept -> const char * override; 

Điều đó nói rằng, hơn là mù quáng sử dụng C++ 11/C++ 14 tính năng, chọn những cái tốt nhất phản ánh ý định của bạn. Không có một số quy tắc chỉ yêu cầu sử dụng các tính năng C++ 11/C++ 14 nếu có các lựa chọn thay thế cũ hơn để đạt được điều tương tự.

0

Vì bạn cũng hỏi về C++ 14, đối với kịch bản của bạn, điều này tốt hơn cú pháp kiểu hậu tố trả về;

virtual auto what() const noexcept override; 
+1

... trong những trường hợp bạn được phép bỏ qua kiểu trả về hoàn toàn (ví dụ: nó có thể là bất hợp pháp khi bạn có nhiều câu lệnh 'return', ví dụ) –

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