Cả hai const
và constexpr
có thể được áp dụng cho các biến và chức năng. Mặc dù chúng giống nhau, nhưng thực tế chúng là những khái niệm rất khác nhau.
Cả hai const
và constexpr
có nghĩa là giá trị của chúng không thể thay đổi sau khi khởi tạo. Ví dụ:
const int x1=10;
constexpr int x2=10;
x1=20; // ERROR. Variable 'x1' can't be changed.
x2=20; // ERROR. Variable 'x2' can't be changed.
Sự khác biệt chính giữa const
và constexpr
là thời điểm mà các giá trị khởi tạo của chúng được biết đến (được đánh giá). Mặc dù các giá trị của const
các biến có thể được đánh giá ở cả thời gian biên dịch và thời gian chạy, constexpr
luôn được đánh giá ở thời gian biên dịch. Ví dụ:
int temp=rand(); // temp is generated by the the random generator at runtime.
const int x1=10; // OK - known at compile time.
const int x2=temp; // OK - known only at runtime.
constexpr int x3=10; // OK - known at compile time.
constexpr int x4=temp; // ERROR. Compiler can't figure out the value of 'temp' variable at compile time so `constexpr` can't be applied here.
Lợi thế chính để biết giá trị được biết vào thời gian biên dịch hay thời gian chạy là thực tế là các hằng số thời gian biên dịch có thể được sử dụng bất cứ khi nào cần các hằng số thời gian biên dịch. Chẳng hạn, C ++ không cho phép bạn chỉ định mảng C với độ dài thay đổi.
int temp=rand(); // temp is generated by the the random generator at runtime.
int array1[10]; // OK.
int array2[temp]; // ERROR.
Vì vậy, nó có nghĩa là:
const int size1=10; // OK - value known at compile time.
const int size2=temp; // OK - value known only at runtime.
constexpr int size3=10; // OK - value known at compile time.
int array3[size1]; // OK - size is known at compile time.
int array4[size2]; // ERROR - size is known only at runtime time.
int array5[size3]; // OK - size is known at compile time.
Vì vậy, const
các biến có thể định nghĩa cả hai hằng số thời gian biên dịch như thế size1
có thể được sử dụng để chỉ định kích thước mảng và hằng số thời gian chạy giống như size2
chỉ được biết trong thời gian chạy và không thể được sử dụng để xác định kích thước mảng. Mặt khác, constexpr
luôn xác định các hằng số thời gian biên dịch có thể chỉ định kích thước mảng.
Cả hai const
và constexpr
có thể được áp dụng cho các chức năng quá. Một const
chức năng phải là một hàm thành viên (phương pháp, điều hành), nơi ứng dụng của const
phương tiện từ khóa đó phương pháp này không thể thay đổi các giá trị của thành viên của họ (không tĩnh) lĩnh vực. Ví dụ.
class test
{
int x;
void function1()
{
x=100; // OK.
}
void function2() const
{
x=100; // ERROR. The const methods can't change the values of object fields.
}
};
A constexpr
là một khái niệm khác. Nó đánh dấu một hàm (thành viên hoặc không phải thành viên) là hàm có thể được đánh giá tại thời gian biên dịch nếu các hằng số thời gian biên dịch được truyền làm đối số của chúng . Ví dụ bạn có thể viết cái này.
constexpr int func_constexpr(int X, int Y)
{
return(X*Y);
}
int func(int X, int Y)
{
return(X*Y);
}
int array1[func_constexpr(10,20)]; // OK - func_constexpr() can be evaluated at compile time.
int array2[func(10,20)]; // ERROR - func() is not a constexpr function.
int array3[func_constexpr(10,rand())]; // ERROR - even though func_constexpr() is the 'constexpr' function, the expression 'constexpr(10,rand())' can't be evaluated at compile time.
Nhân tiện, các constexpr
hàm là các hàm C ++ thông thường có thể được gọi ngay cả khi các đối số không liên tục được truyền. Nhưng trong trường hợp đó, bạn sẽ nhận được các giá trị không phải là constexpr.
int value1=func_constexpr(10,rand()); // OK. value1 is non-constexpr value that is evaluated in runtime.
constexpr int value2=func_constexpr(10,rand()); // ERROR. value2 is constexpr and the expression func_constexpr(10,rand()) can't be evaluated at compile time.
Cũng constexpr
có thể được áp dụng cho các hàm thành viên (phương thức), toán tử và thậm chí các hàm tạo. Ví dụ.
class test2
{
static constexpr int function(int value)
{
return(value+1);
}
void f()
{
int x[function(10)];
}
};
Một mẫu 'điên' hơn.
class test3
{
public:
int value;
// constexpr const method - can't chanage the values of object fields and can be evaluated at compile time.
constexpr int getvalue() const
{
return(value);
}
constexpr test3(int Value)
: value(Value)
{
}
};
constexpr test3 x(100); // OK. Constructor is constexpr.
int array[x.getvalue()]; // OK. x.getvalue() is constexpr and can be evaluated at compile time.
constexpr
tạo một hằng số thời gian biên dịch;const
đơn giản có nghĩa là giá trị không thể thay đổi.