2015-11-01 14 views
18

Ví dụ:Chúng ta có thể bỏ qua const trên các biến cục bộ trong các hàm constexpr không?

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    // Can we omit const? 
    const int x = g(); 
    const int y = 10; 

    return x + y; 
} 

bất kỳ điểm đến bao giờ khai báo các biến cục bộ trong một hàm constexpr với const?

Không phải là constexpr chức năng với const biến cục bộ tương đương cho những người không có const?

Nói cách khác, không constexpr trên hàm áp đặt (ngụ ý) const trên các biến cục bộ của nó?

+9

Tôi không đồng ý với tiền đề của bạn bỏ qua 'const' làm cho một chức năng trông" sạch hơn ". Ngoài ra, không, tôi không nghĩ vậy. Nhưng tôi không có 'constexpr't. –

+3

Bạn thậm chí có thể [thay đổi chúng] (http://ideone.com/L4Oa68)! (Và nó hợp lý, nó không làm cho hàm _ không thuần túy) – Lol4t0

+2

@LeoHeinsaar Tôi nghĩ bạn có nghĩa là ít ký tự trắng hơn, bởi vì nếu không nó có thể được tạo ra một cách trivially 'cleaner' theo định nghĩa đó theo cách phổ biến sẽ được hiểu là không đọc được . – hvd

Trả lời

23

Những lập luận tương tự cho khai báo biến như const trong phi constexpr chức năng cũng áp dụng cho constexpr chức năng:

  • Khai báo một biến const tài liệu thực tế là nó sẽ không bao giờ được thay đổi. Điều này có thể trong một số trường hợp giúp làm cho hàm dễ đọc hơn.
  • Khai báo biến số const ảnh hưởng đến độ phân giải quá tải và có thể làm cho h(x) giải quyết h khác nhau tùy thuộc vào việc xconst.

Tất nhiên, theo hướng ngược lại, như đã đề cập trong ý kiến ​​đã:

Ngay cả trong constexpr chức năng, các biến địa phương có thể được thay đổi. Nếu các biến đó sau đó được thay đổi để chúng là const, các nỗ lực thay đổi chúng sẽ không còn được chấp nhận nữa.

+0

Tôi nghĩ đây là một câu trả lời hay. Không khó hơn, nó có thể tạo ra một ấn tượng rằng 'constexpr' trên một hàm bằng cách nào đó ngụ ý (ngụ ý) constness trên tất cả mọi thứ bên trong nó, bao gồm các biến cục bộ (bởi vì, ví dụ, bạn không thể gọi một hàm không constexpr từ nó). Cảm ơn. –

+4

Tất nhiên, const biến cục bộ không thể di chuyển từ khi trở về. Tôi rất cảnh giác với người dân địa phương vì lý do này. –

1

Nói chung, một hàm không thể được đánh giá tại thời gian biên dịch và do đó không thể được gọi trong biểu thức hằng số. Chỉ định một hàm như constexpr chỉ ra rằng nó có thể được sử dụng trong các biểu thức hằng số NẾU các đối số đầu vào của nó là các hằng số. Ví dụ: ...

constexpr int n = func(7); 

... phải được đánh giá vào thời gian biên dịch.

Đó là ý nghĩa của hàm constexpr trước. Đây là trường hợp, nó không làm theo các biến cục bộ bên trong hàm không cần phải được chỉ định const.

16

Trong ví dụ cụ thể này các biến cục bộ sẽ được công bố tốt nhất constexpr, không const, bởi vì họ thể được tính tại thời gian biên dịch:

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    constexpr int x = g(); 
    constexpr int y = 10; 

    return x + y; 
} 

Khi f() được gọi vào thời gian chạy, mà không có sự constexpr trên xy, (có hoặc không có const trên xy) bạn đang cung cấp cho trình biên dịch tùy chọn khởi tạo xy tại thời gian chạy thay vì biên dịch thời gian.Với constexpr trên xy, trình biên dịch sẽ tính xy tại thời gian biên dịch, ngay cả khi f() được thực hiện tại thời gian chạy.

Tuy nhiên, trong một chức năng khác, không thể luôn sử dụng constexpr. Ví dụ, nếu f()g() mất một tham số:

constexpr int g(int z) { return z+30; }  

constexpr int f(int z) 
{ 
    const int x = g(z); 
    constexpr int y = 10; 

    return x + y; 
} 

Bây giờ x không thể được đánh dấu constexprz có thể không phải là một thời gian biên dịch liên tục, và hiện nay là không có cách nào để đánh dấu nó như vậy. Vì vậy, trong trường hợp này, đánh dấu xconst là cách tốt nhất bạn có thể làm.

+1

Sẽ là hợp lý khi yêu cầu hàm ý 'constexpr' trên các biến cục bộ không bị thay đổi? –

+0

@LeoHeinsaar: Tôi không sợ. Trong ví dụ này, nếu 'g()' không được đánh dấu 'constexpr' thì sao? Trong trường hợp đó, kết quả là 'x' không thể được đánh dấu' constexpr', và trình biên dịch nằm trong quyền của nó để tính toán 'g()' tại thời gian chạy. Có lẽ 'g()' cần thực hiện một cuộc gọi điện thoại để có được kết quả của nó ... –

+1

Nếu g() không được đánh dấu 'constexpr', nó có được biên dịch không? Cách tôi hiểu nó là chúng ta chỉ có thể gọi các hàm 'constexpr' từ các hàm' constexpr' ... –

3

Bạn không chỉ có thể , nhưng đôi khi bạn phải (ví dụ nếu những thay đổi biến), ví dụ:

constexpr size_t f(size_t n) { 
    size_t val = 1; 
    if (n == 0) val++; 
    return val; 
} 
char arr0[f(0)] = {'a', 'x'}; 
char arr1[f(1)] = {'y'}; 

là tốt trong C++ 14.

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