對於對象來說
const指的是編譯期常量和運行時常量,兩者並沒有區分
constexpr特指編譯期常量
對於函數來說
const可以修飾類的成員函數,被修飾的函數在執行期間不會改變對象的值。
class Person{
public :
string getName() const;
void setAge() const;
private :
string name;
mutable int age;
}
// 可以執行
string Person::getName() const
{
return this->name;
}
// 不能執行
string Person::getName() const
{
this->name = "test";
return this->name;
}
//可以執行
void Person::setAge() const
{
++age;
}
假設此函數未public限定,且name數據成員沒有使用mutable
修飾,那么此函數在調用期間不會改變this所指的對象,也就是說,如果某個被修飾成const
的成員函數在執行期間改變了this中的數據成員,那么這個函數會報錯。
如果在此類函數中改變了使用mutable
修飾的數據成員,這是允許的。
constexpr修飾的函數,返回值不一定是編譯期常量
constexpr int foo(int i)
{
return ++i;
}
int main()
{
int i = 10;
// 成功調用
array<int, foo(5)> arr;
// 成功調用
foo(i);
// 錯誤
array<int, foo(i)> arr1;
return 0;
}
上面的代碼中,第一次和第二次執行都是正確的,第三次執行會報錯。
- 第一次中,foo(5)使用的是常量表達式5,所以在編譯期間就可以得出結果,從而確定array的大小,所以這個聲明是正確的;
- 第二次中,foo(i)使用的是變量,在運行時可以得到結果,所以這個調用是正確的;
- 第三次中,foo(i)使用的是變量,在運行時才能得到結果,但array的聲明要求在編譯期就必須要確定其大小,且不能改變,所以這個生命是錯誤的。
所以,對於constexpr修飾的函數,如果其傳入的參數可以在編譯期算出來,那么這個函數就會產生編譯期的值。如果傳入的參數不能在編譯時期計算出來,那么constexpr修飾的函數就和普通函數一樣了。