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ì function
là constexpr
, 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.
"* 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ì? –
Bạn có biết bộ khởi tạo * brace-hoặc-equalizer * là gì không? –
@ 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. –