2016-02-10 19 views
9

Sau khi thư giãn các quy tắc cho các constexpr có vẻ như các chức năng này có thể được sử dụng ở khắp mọi nơi. Chúng có thể được gọi trên cả hai biến cố định (constexpr) và local (mutable). Vì vậy, đối với tôi nó có vẻ như chỉ là một gợi ý cho trình biên dịch (như inline). Tôi chỉ cần viết nó ở khắp mọi nơi và loại bỏ nó nếu trình biên dịch phàn nàn. Vì vậy, trình biên dịch dường như biết tất cả mọi thứ nếu một chức năng có thể được đánh giá tại thời gian biên dịch hay không. Tại sao nó không phải là hành vi mặc định và tại sao tôi phải đánh dấu bất cứ điều gì như constexpr?Tại sao constexpr không phải là mặc định cho tất cả các chức năng?

+0

Đối với một điều, một số thứ không được phép trong một hàm 'constexpr', ngay cả sau khi thư giãn C++ 14. – 101010

+2

Điều tương tự có thể được nói về 'const' và' noexcept' bằng cách này. –

+0

Const là một chút khác nhau do const_cast và các hoạt động con trỏ khác. – Gzp

Trả lời

15

constexpr là bảo đảm giao diện. Nó có nghĩa là bạn có thể sử dụng hàm trong các biểu thức hằng số.

Khi mọi người có thể sử dụng chúng trong các biểu thức liên tục, họ sẽ làm như vậy. Nhưng nếu bạn không có nghĩa là cho chức năng của bạn để được sử dụng theo cách đó? Điều gì xảy ra nếu trước đây bạn đã triển khai đơn giản đã xảy ra có thể có khả năng, nhưng trong bản sửa đổi sau, bạn cần thay đổi điều đó (ví dụ: vì bây giờ bạn cần thêm đầu ra nhật ký)?

Nếu bạn loại bỏ điểm đánh dấu constexpr, việc sử dụng trong biểu thức không đổi sẽ ngừng biên dịch, khi nó hoạt động trước đó và người dùng chức năng của bạn sẽ khó chịu. Tốt hơn là không làm cho hàm constexpr ở vị trí đầu tiên, cho phép bạn tự do thay đổi nó sau này.

Nhưng nếu trình biên dịch tự động tạo ra hàm constexpr, bạn không có lựa chọn đó.

+0

Vì vậy, nó là một (giao diện) tài sản của một API được thiết kế để sử dụng "bên ngoài" (ví dụ trong một thư viện) và nó không phải dành cho trình biên dịch làm thế nào để tối ưu hóa. (Có phải không?) Nếu như vậy tốt hơn là đảo ngược hướng và nêu rõ rằng một hàm không phải là constexpr, nhưng so với tính tương thích ngược đã mất (và sẽ có các vấn đề khác chắc chắn :)) – Gzp

+0

Có, nó có rất ít việc phải làm với tối ưu hóa. Tối ưu hóa được thực hiện dựa trên những gì mã thực sự làm, không cho dù nó được đánh dấu constexpr hay không. Nếu hàm của bạn là 'int f() {return 7; } 'và' int x = f() '; mã sẽ là' x = 7; '. Việc tuyên truyền liên tục đã ở trong các trình biên dịch trong 25 năm qua, ít nhất. –

+0

@Gzp: constexpr (trên các hàm) không liên quan gì đến việc biên dịch. – MikeMB

2

Như đã chỉ here, nó làm cho sự khác biệt để sử dụng chức năng mẫu chuyên môn, định nghĩa với constexpr specifier hoặc không (ví dụ) SFINAE bối cảnh:

Việc bổ sung constexpr đang gây ra chức năng mẫu để được thuyết minh trong các ngữ cảnh không được đánh giá nếu không thì không.

Vì vậy, đôi khi sẽ là hành vi không mong muốn để có tất cả các hàm được định nghĩa ngầm định là constexpr.

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