Sự Khác Biệt Giữa const Và constexpr

Cập nhật ngày: 30/11/2021 - Đã có 675 lượt xem bài viết này!
Sự Khác Biệt Giữa const Và constexpr
Trong lịch sử phát triển của C++, những lập trình viên hỗ trợ xây dựng lên C++ ngày càng hoàn thiện hơn, cải tiến tốc độ biên dịch là yếu tố rất được quan tâm đến. Từ đó qua các thế hệ C++ tiêu biểu như C++98, C++11, C++14 và tiếp đến là C++17, xuất hiện nhiều hơn các từ khóa mới, khái niệm mới. Trong bài viết này, tôi sẽ giải thích const và constexpr - một khái niệm được đưa ra từ C++11.

Sự Khác Biệt Giữa const Và constexpr

Mở đầu

Đối với khái niệm const, trong bài viết này tôi sẽ không đi quá sâu để phân tích, đây là một khái niệm khá quen thuộc trong lập trình C++, bạn có thể tìm hiểu một số vào viết Thao Tác Với constant Với C++. Tôi sẽ làm rõ khái niệm constexpr và so sánh với const.

Nhắc lại về const

Tôi sẽ tổng hợp một số điểm quan trọng trong bài viết trên để tiện hơn cho bạn:

const (Constant – Hằng) là từ khóa để chỉ định một biến hay đối tượng nào đó là hằng, tức là không thay đổi được giá trị, mọi hành động thay đổi giá trị của hằng đều được compiler báo lỗi.

const được dùng trong các trường hợp đối tượng cần định là biến thông thường, biến tham chiếu và tham số của hàm.

 

int main()

{

// Biến thông thường.

const int x = 7;



// Biến tham chiếu

int y = 8;

const int &A = y;



// Biến con trỏ

int z = 9;

int *const p = &x;



return 0;

}



// Tham số của hàm

void printName(const char * ID)

{

// phần xử lý.

}

Bạn có thể tìm hiểu cách sử dụng kỹ hơn trong bài viết trên. Nhưng từ các cách sử dụng trên, ta rút ra được ý nghĩa của const, mà tôi muốn bạn ghi nhớ:
const: Không được thay đổi giá trị.

Định nghĩa tổng quát về constexpr

constexpr là từ khóa có chức năng yêu cầu trình biên dịch tính toán hàm hoặc biến tại thời điểm biên dịch. Các biến và hàm này được sử dụng sau đó nếu được sử dụng với một số tham số phù hợp.
constexpr: thực thi tính toán tại thời điểm biên dịch.

Constexpr variable

Khi khai báo một biến dạng constexpr thì so với const, nó cũng được hiểu là không thể thay đổi giá trị, nhưng khác là trong thời gian biên dịch, còn const sẽ thuộc thời gian thực thi. Tuy nhiên muốn sử dụng constexpr cần phải tuân theo những quy định sau:

  • Kiểu của biến được thể hiện phải là LiteralType.

  • Nó cần được khởi tạo ngay tại thời điểm định nghĩa biến.

  1. constexpr int a = 2;

Constexpr function

Khi khai báo 1 hàm là constexpr function, hàm này phải thỏa các điều kiện:

  • Nó không phải là virtual function.

  • Kiểu trả về của hàm phải là LiteralType.

  • Các biến tham số của hàm phải là LiteralType.

    constexpr int add(int a, int b)
    
    {
    
    return a + b;
    
    }

Constexpr và thời gian biên dịch

Điều quan trọng nhất của constexpr là biểu thức được tính tại thời gian biên dịch, ta sẽ xét ví dụ sau để làm rõ điều này:

 

int add_vectors_size(const std::vector & a, const std::vector & b)

{

return a.size() + b.size();

}

Như đã làm với hàm add phía trên, ta chuyển hàm add_vectors_size về dạng constexpr:

 

constexpr int add_vectors_size(const std::vector & a, const std::vector & b)

{

return a.size() + b.size();

}

Tuy nhiên, cách làm này là không chính xác, vì tại thời điểm biên dịch, ta có tham số truyền vào là hai vector, tuy nhiên ta lại không biết kích thước của vector đó, vậy nên hàm này không thể thực hiện được.

Đối với một ví dụ khác:

 

template 

int add_arrays_size(const std::array & a,

const std::array & b)

{

return a.size() + b.size();

}

Hàm này lại có thể hoàn toàn thực hiện được, do tại thời điểm biên dịch, ta hoàn toàn biết size của hai mảng a và b.

Tổng kết

Tuy rằng hai từ khóa này khá giống nhau, nhưng đã thấy được rằng chúng có ý nghĩa hoàn toàn khác biệt, từ bài viết hi vọng bạn có thể hiểu được mục đích tạo nên từ khóa constexpr.

Xem khóa đào tạo nhân sự theo danh mục!

Xem các khóa đào tạo nhân sự