2017-02-02 29 views
8
int x = 1; // Not Constant 

class A { 
    public: 
     int value = x; 
     int value2 { x }; 
     A(int a)  : value(x), value2(x) {} 
     A(int a, int b) : value{ x }, value2{ x } {} 
     constexpr A() : value{ 0 }, value2{ 0 } {} 
}; 

constexpr int function(A obj1, A obj2, A obj3, A obj4, A obj5, A obj6, A obj7){ 
    return 1; 
} 

int main(){ 

    int y = 2; // Not Constant 
    A obj1 (y); 
    A obj2 { y }; 
    A obj3 = y ; 
    A obj4 = { y }; 
    A obj5 (y, y); 
    A obj6 { y, y); 
    A obj7 = { y, y }; 
    int var = function(obj1, obj2, obj3, obj4, obj5, obj6, obj7); 

    return 0; 
} 

C++ 11 tiêu chuẩn (ISO/IEC 14882: 2011), mục 3.9, khoản 10 bang (tôi nhấn mạnh):Literal Loại Class trong C++ 11/C++ 14

Loại là loại chữ nếu có:

  • loại vô hướng; hoặc
  • loại tham chiếu; hoặc
  • một kiểu lớp (khoản 9) mà có tất cả các thuộc tính sau:
    • nó có một destructor tầm thường,
    • mỗi cuộc gọi constructor và đầy đủ thể hiện trong cú đúp-hoặc-equal- initializers cho các thành viên dữ liệu không tĩnh (nếu có) là một biểu thức không đổi (5.19),
    • nó là một loại tổng hợp (8.5.1) hoặc có ít nhất một constructor constexpr hoặc constructor template không phải là bản sao hoặc di chuyển hàm tạo và
    • có tất cả các thành viên dữ liệu không tĩnh và các lớp cơ sở của các kiểu chữ; hoặc
  • một mảng loại chữ.

Theo tôi, có tính đến viên đạn in đậm, class A không phải là một kiểu chữ trong C++ 11 vì có những cuộc gọi constructor và một cú đúp-hoặc-bằng-initializers cho dữ liệu không tĩnh các thành viên không phải là biểu thức không đổi. Tôi đã thử đặt constexpr trước định nghĩa hàm tạo và cũng chỉ định lời gọi hàm tạo cho biến số constexpr để kiểm tra xem trình biên dịch có thực sự phàn nàn không vì đó không phải là biểu thức không đổi. Tuy nhiên, cả Clang và GCC đều biên dịch thành công. Vì vậy, tôi có thể sai.

  • Có ai biết tại sao class A là một loại chữ?

Dấu đầu dòng in đậm đã bị xóa trong C++ 14 (N3652), vì vậy tôi hiểu class A là một loại chữ trong C++ 14. Tôi cần biết vì functionconstexpr, do đó each of its parameter types shall be a literal type (C++ 11/C++ 14 Standard, Mục 7.1.15, Đoạn 3).

EDIT: Trong bài đăng gốc, tôi đã sử dụng một ví dụ đơn giản để dễ đọc hơn và giải thích rằng tôi đã thử nhiều kết hợp. Bây giờ tôi đã cập nhật ví dụ với một số kết hợp để cho thấy tôi đã thử các hàm tạo khác nhau, các định nghĩa và các khởi tạo thành viên dữ liệu không tĩnh. Cảm ơn.

+0

"* Có ai biết lý do lớp A là một loại chữ không? *" Nó không có trong C++ 11. Và không có mã nào bạn đã hiển thị * yêu cầu * nó phải là một loại chữ. Vậy vấn đề là gì? –

+0

Bạn có biết bộ khởi tạo * brace-hoặc-equalizer * là gì không? –

+0

@ T.C. Tôi nghĩ rằng * brace-hoặc-equalizer initializer * này là 'int x {y}' hoặc 'int x = y'. Tôi thường nói * member-initializer-list * cho initializations trong constructor như khi khởi tạo 'value' trong' A (int z): value (x) {} ', nhưng tôi cũng đã đọc rất nhiều người đề cập đến điều này * brace-hoặc-equalizer khởi tạo *. Hãy sửa tôi nếu tôi phạm sai lầm. Trong mọi trường hợp, tôi đã thử nhiều kết hợp của dấu ngoặc, bằng, vv khởi tạo cả cho chính đối tượng và cho biến 'giá trị' trong hàm tạo và kết quả là giống nhau. Cảm ơn. –

Trả lời

3

Có ai biết lý do lớp A là một loại chữ không?

Nó không có trong C++ 11, nhưng trong C++ 14, vì lý do bạn trích dẫn trong bài đăng của mình. Tuy nhiên ...

Tuy nhiên, cả Clang và GCC đều biên dịch thành công. Vì vậy, tôi có thể sai.

Bạn không sai. Không phải là clang và gcc. Mã này, thực sự, được hình thành tốt mặc dù A không phải là một loại chữ ... chỉ đơn giản bởi vì không có gì đòi hỏi nó phải là một loại chữ. function có thể là một hàm constexpr, nhưng nó không được gọi là một biểu thức liên tục. var không phải là đối tượng constexpr, do đó, không có yêu cầu bắt buộc nào đối với tất cả các đối tượng thuộc loại chữ. Đã bạn đã thử:

constexpr int var = function(...); 

sau đó mã sẽ được vô hình thành, như trong trường hợp này, function(...) sẽ cần phải là một biểu thức hằng số lõi, đòi hỏi loại đen, đó là một yêu cầu rằng trong C + +11 A không thành công. (Trên thực tế, bạn cũng có vấn đề trong C++ 14 rằng không có ai trong số các đối tượng Aconstexpr đối tượng).