2013-04-29 40 views
50

Có sự khác biệt nào giữa việc khai báo hằng số dấu phẩy động như một biến số static constexpr và một hàm như trong ví dụ dưới đây hay chỉ là vấn đề về kiểu dáng?biến constexpr tĩnh so với hàm

class MY_PI 
{ 
public: 
    static constexpr float MY_PI_VAR = 3.14f; 
    static constexpr float MY_PI_FUN() { return 3.14f; } 
} 

Trả lời

51

constexpr chức năng

Chức năng có một lợi thế mà các biến tự do không có (cho đến khi C++ 14 đó là): họ có thể dễ dàng được templated nếu không có soạn sẵn lớp. Điều đó có nghĩa bạn có thể có pi của bạn với một độ chính xác tùy thuộc vào một mẫu đối số:

template<typename T> 
constexpr T pi(); 

template<> 
constexpr float pi() { return 3.14f; } 

template<> 
constexpr double pi() { return 3.1415; } 

int main() 
{ 
    constexpr float a = pi<float>(); 
    constexpr double b = pi<double>(); 
} 

Tuy nhiên, nếu bạn quyết định sử dụng một hàm static thành viên thay vì một chức năng miễn phí, nó sẽ không thể ngắn hơn cũng không easir viết hơn một biến thành viên static.

constexpr biến

Lợi thế chính của việc sử dụng biến là ... tốt. Bạn muốn có một hằng số, phải không? Nó làm rõ mục đích và đó có thể là một trong những điểm quan trọng nhất tại đây.

Bạn vẫn có thể có một hành vi tương đương với một lớp học, nhưng sau đó, bạn sẽ phải sử dụng nó như thế này nếu lớp học của bạn là một lớp chứa các hằng số toán học linh tinh:

constexpr float a = constants<float>::pi; 

Hoặc như thế này nếu lớp học của bạn chỉ có nghĩa là để đại diện cho pi:

constexpr double = pi<double>::value; 

Trong trường hợp đầu tiên, bạn có thể thích sử dụng các biến vì nó sẽ ngắn hơn để viết và đó thực sự sẽ cho thấy rằng bạn đang sử dụng một hằng số và không cố gắng để tính toán điều gì đó. Nếu bạn chỉ có một lớp đại diện cho pi, bạn có thể đi với một hàm constexpr miễn phí thay vì toàn bộ một lớp. IMHO sẽ đơn giản hơn.

C++ 14: constexpr variable templates

Tuy nhiên, lưu ý rằng nếu bạn chọn để sử dụng C++ 14 thay vì C++ 11, bạn sẽ có thể viết các loại sau đây của constexpr mẫu biến:

template<typename T> 
constexpr T pi = T(3.1415); 

điều đó sẽ cho phép bạn viết mã của bạn như thế này:

constexpr float a = pi<float>; 

Trong C++ 14, điều này có thể là cách ưa thích để làm việc. Nếu bạn đang sử dụng một phiên bản cũ của tiêu chuẩn, hai đoạn đầu tiên vẫn giữ.

+0

C++ 14? Cái gì thế? : D – cubuspl42

+4

@ cubuspl42 Tiêu chuẩn C++ tiếp theo sẽ có sẵn vào năm tới. GCC và Clang đã bắt đầu triển khai một số tính năng. – Morwenn

+0

Bạn có thể cung cấp bất kỳ liên kết nào không? – cubuspl42

Các vấn đề liên quan