2015-07-14 17 views
5

Tôi đã đi qua mới C++ 14 chữ ký cho std::max chức năng:Rắc rối hiểu biết C++ 14 Relaxed hạn chế constexpr

template< class T > 
const T& max(const T& a, const T& b); // (C++11) 

template< class T > 
constexpr const T& max(const T& a, const T& b);// (C++14) 

Tôi đã đọc về hạn chế constexpr Relaxed đề nghị cho C++ 14 nhưng tôi vẫn không hiểu tại sao giá trị trả về chức năng này có thể constexpr

Ví dụ:

std::vector<int> a, b; 
//This does not compile but as my understadnding of `constexpr` this should 
int array[std::max(a.size(), b.size()]; (1) 
//This is trivial use that does compile 
int array[std::max(1,2)]; (2) 

Khi gọi std::max trong (1) constexpr bị bỏ qua?

+0

'constexpr' ở đây không có nghĩa là giá trị trả về hàm là' constexpr'. Nó có nghĩa là hàm là 'constexpr'. (Tương tự như cách 'static int x();' không có nghĩa là 'x' trả về một int tĩnh). –

Trả lời

10

Vấn đề cơ bản không liên quan trực tiếp đến các quy tắc constexpr thoải mái, hàm constexpr chỉ là biểu thức liên tục nếu đối số là biểu thức không đổi. Trong trường hợp thứ hai của bạn:

int array[std::max(1,2)]; 

hoạt động này vì các chữ số nguyên thực sự là biểu thức không đổi.

C++ 11 cụ thể hơn trong trường hợp này, dự thảo tiêu chuẩn C++ 11 trong phần 5.19[expr.const] đưa ra các trường hợp biểu thức phụ không được coi là biểu thức liên tục và chứa sau:

một lời gọi của một hàm constexpr với lập luận rằng, khi thay bằng cách thay thế chức năng gọi (7.1.5), không tạo ra một biểu thức hằng số;

trong C++ 14 đoạn này đã được gỡ bỏ và chúng tôi có ngoại lệ sau đây:

một lời gọi của một hàm khác hơn là một constructor constexpr cho một lớp đen, một chức năng constexpr, hoặc một yêu cầu tiềm ẩn của destruct tầm thường (12.4) [Lưu ý: Độ phân giải quá tải (13.3) là được áp dụng như thường lệ —thêm ghi chú];

và chúng ta phải sử dụng phần còn lại của các quy tắc liên quan đến các đối số (tiểu biểu) với.

Trong trường hợp thứ nhất:

int array[std::max(a.size(), b.size()]; 

std::vector::size không được đánh dấu constexpr và vì vậy nó thuộc ngoại lệ trích dẫn ở trên.

Cũng lưu ý rằng trong phần 7.1.5[dcl.constexpr] chúng tôi có như sau:

Một cuộc gọi đến một hàm constexpr tạo ra kết quả tương tự như một cuộc gọi đến một chức năng không constexpr tương đương trong tất cả các khía cạnh ngoại trừ một cuộc gọi tới hàm constexpr có thể xuất hiện trong một biểu thức liên tục.

Việc chuyển đối số cho hàm constexpr không phải là biểu thức liên tục chỉ có nghĩa là biểu thức không có sẵn để sử dụng trong ngữ cảnh yêu cầu biểu thức không đổi.

Khi dyp chỉ ra rằng std::max không được thực hiện constexpr trong C++ 11 do với các vấn đề khác nhau. nó bị lãng quên thấy N3856 mà nói:

giấy ngắn này đề xuất để thực hiện các chức năng tiêu chuẩn min và max constexpr. Họ đứng đầu trong danh sách các trường hợp thúc đẩy al- tham số hạ thấp tham số cho các hàm constexpr trong C++ 11. Họ bị lãng quên sau khi thay đổi ngôn ngữ cốt lõi đã được chấp nhận

Để tham khảo chúng ta biết rằng 12 là hằng số biểu hiện từ phần 5.19 mà nói:

Một biểu thức hằng đen là một biểu thức hằng lõi prvalue loại chữ, nhưng không phải kiểu con trỏ. An biểu thức hằng số không thể thiếu là một biểu thức hằng số theo nghĩa đen của kiểu liệt kê không thể tách rời hoặc không được điều chỉnh. [...]

+0

Tôi nghĩ nếu hàm được khai báo là 'constexpr' hơn nó chỉ có thể được gọi với các giá trị có thể được tính trong thời gian biên dịch, nếu không nó sẽ là lỗi thời gian biên dịch ... –

+0

@AlejandroFreeman câu trả lời cập nhật –

+0

@dyp bạn biết tôi đã tìm thấy [ lwg 2350] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3893.html#2350) nhưng tôi đã nhầm lẫn bởi vì nó đi từ wp -> mở và tôi không thể tìm ra lý do –

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