2013-08-20 41 views
7

Tôi đang học C++ 11 và quan tâm đến các chữ cái do người dùng xác định. Vì vậy, tôi quyết định chơi một chút với nó. Một số ngôn ngữ có cú pháp như sau:C++ 11 literal do người dùng định nghĩa

int n = 1000_000_000; 

Tôi đã thử mô phỏng tính năng này trong C++ 11.

inline constexpr unsigned long long operator "" _000 (unsigned long long n)noexcept 
{ 
     return n * 1000; 
} 

inline constexpr unsigned long long operator "" _000_000 (unsigned long long n)noexcept 
{ 
     return n * 1000*1000; 
} 

inline constexpr unsigned long long operator "" _000_000_000 (unsigned long long n)noexcept 
{ 
     return n * 1000*1000*1000; 
} 

int main(){ 
    constexpr auto i = 100_000; // instead of 100000 
    constexpr auto j = 23_000_000; // instead of 23000000; 
} 

Nhưng đối với trường hợp chung tôi không thể mô phỏng nó, ví dụ:

auto general_case = 123_456_789; // không thể biên dịch

Câu hỏi của tôi là "Tôi có thể mô phỏng cho trường hợp chung như trên bằng C++ 11 không?".

+2

Tính năng này có hoạt động với 1_000_000 không? Cá nhân tôi sẽ sử dụng chữ người dùng tùy chỉnh và các chữ cái K M G (kilo mega giga). – dtech

+0

1_000_000 được biên soạn !!! –

+0

@ddriver chỉ có vấn đề với đó là sau đó bạn không thể là chính xác – aaronman

Trả lời

4

Điều này là không thể với các chữ được người dùng xác định trong phiên bản C++ 11 của ngôn ngữ như bây giờ. Các chữ cái do người dùng định nghĩa hỗ trợ định dạng giới hạn cho các tham số, dường như không hỗ trợ tham số bên phải, chuỗi, cộng với có vấn đề biểu diễn các số bắt đầu bằng 0 dưới dạng số thực. Vì vậy, nó không phải là đi.

Cách tiếp cận hiện tại của bạn xác định _000 và cứ như là các chữ cái độc lập, do đó trình biên dịch sẽ chỉ hoạt động với chúng và không khác. Nó không giống như _ là nhà điều hành và 000 là một số thông số bạn có thể làm việc với không may.

Tuy nhiên, bạn có thể sử dụng hậu tố thư.

long long constexpr operator"" K (long double n) { 
    return n * 1000; 
} 
long long constexpr operator"" M (long double n) { 
    return n * 1000000; 
} 
long long constexpr operator"" G (long double n) { 
    return n * 1000000000; 
} 

Và sau đó:

0.05M == 50000; 
123.232K == 123232 
1.000000001G == 1000000001 

Chắc chắn, trường hợp cuối cùng loại đánh bại mục đích, bởi vì một lần nữa bạn có nhiều zero mà không cần chỉ thị giác ... Vì vậy, bạn có thể đi cho một cái gì đó như:

1.G + 1 == 1000000001 // much clearer 1 billion + 1 

Điều này làm cho nó hơi xấu xí, vì chữ mong đợi một số thực và sẽ không hoạt động với số nguyên trừ khi bạn xác định thêm chữ để sử dụng với số nguyên. Sau đó, bạn chỉ có thể sử dụng 1G thay thế.

Ngoài ra, cách tiếp cận này có khả năng sẽ tạo ra cảnh báo trình biên dịch, rõ ràng nhóm C++ muốn đặt trước tất cả các hậu tố không có dấu gạch dưới cho "sử dụng trong tương lai". Nếu bạn muốn cảnh báo biến mất, chỉ cần sử dụng _K _M và _G thay thế.

EDIT: Tôi đã xóa giải pháp danh sách khởi tạo, vì nó tạo ra kết quả không hợp lệ với các số như 010, được xử lý dưới dạng bát phân và làm rối các tính toán.

+0

Vâng, bạn đã giải quyết được vấn đề nếu vấn đề là nhiều số 0, nhưng bạn không giải quyết nó cho trường hợp chung (ví dụ: '123456789' ->' 123456.789K' -> '123.456789M' -> không rõ ràng lợi ích) –

+0

@LightnessRacesinOrbit - Tôi đồng ý nó là khá nhiều vô nghĩa, tuy nhiên nó vẫn còn hữu ích như là một ví dụ cho OP, người rõ ràng có sai chữ. Tôi thực sự đã có những kỳ vọng về tham số và chuỗi RHS, có vẻ như các chữ trong dạng hiện tại của chúng khá thô sơ. – dtech

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