9

Tôi đã xem xét một số tính năng mới của C++ 11 và rất ấn tượng với một số người trong số họ, đặc biệt là người dùng định nghĩa literals.Làm thế nào để có được biến nhỏ nhất với C++ 11 người dùng định nghĩa literals

Chúng cho phép bạn xác định các chữ cái theo dạng 999_something trong đó something kiểm soát những gì được thực hiện cho 999 để tạo chữ. Vì vậy, không cần phải sử dụng:

#define MEG * 1024 * 1024 
int ten_meg = 10 M; 

Tôi đã suy nghĩ điều này sẽ được tốt đẹp để thực hiện dấu gạch dưới với số lượng lớn, giống như 1_000_000_blah mà sẽ phù hợp với khả năng đọc của Perl, mặc dù ý tưởng rằng Perl là bằng cách nào đó có thể đọc được có vẻ khá hài hước để tôi :-)

Nó cũng sẽ có ích cho các giá trị nhị phân như 1101_1110_b0011_0011_1100_1111_b.

Rõ ràng là vì các ký tự _, những thứ này sẽ cần phải là kiểu chế độ thô, xử lý chuỗi C và tôi đồng ý với điều đó.

Điều tôi không thể tìm hiểu cách phân phối loại khác nhau dựa trên kích thước toán hạng. Ví dụ:

1101_1110_b 

nên đưa ra một char (giả sử char là 8-bit dĩ nhiên) trong khi:

0011_0011_1100_1111_b 

sẽ cung cấp một loại 16-bit.

Tôi có thể lấy chiều dài của toán hạng từ bên trong chức năng điều hành literal operator"" bản thân (bằng cách đếm ký tự chữ số) nhưng kiểu trả về dường như được cố định vào chức năng vì vậy tôi không thể trở về một loại khác nhau dựa trên này.

Điều này có thể được thực hiện với một hậu tố duy nhất _b trong khung định nghĩa người dùng được xác định hay không.

+0

Tôi không chắc chắn nếu điều này làm việc, nhưng bạn có thể cố gắng để quá tải một số mẫu nhà điều hành bằng chữ cho số bit khác nhau. – celtschk

+1

Nó dường như không hoạt động: http://akrzemi1.wordpress.com/2012/10/29/user-defined-literals-part-iii/ - Tôi nghĩ rằng các mẫu được cho nên có khá dễ dàng để mở rộng để hỗ trợ nhiều loại. – celtschk

+2

Suy nghĩ lại về nó, khả năng * không * công việc đang sử dụng dấu gạch dưới như một phần của số: IIUC '1101_1110_b' sẽ * không * gọi' toán tử "" _ b' với đối số (mẫu) '1101_1110', nhưng' toán tử " "_1110_b' với đối số (mẫu)' 1101'. – celtschk

Trả lời

6

Bạn cần biết kích thước chuỗi của bạn, và cách duy nhất để đạt được điều đó là có gói tham số để sử dụng sizeof.... Bạn sẽ có thể đạt được những gì bạn muốn với một mẫu variadic operator"":

#include <cstdint> 
#include <type_traits> 

template<char... String> 
auto operator "" _b() 
    -> typename std::conditional<sizeof...(String) <= 8, 
     uint8_t, 
     typename std::conditional<sizeof...(String) <= 16, 
      uint16_t, 
      uint32_t 
     >::type 
    >::type 
{ 
    // Do whatever you want here 
} 

Và đây là một trường hợp thử nghiệm:

int main() 
{ 
    auto a = 10000001_b; 
    auto b = 100000001_b; 

    std::cout << std::boolalpha; 
    std::cout << std::is_same<decltype(a), uint8_t>::value << "\n"; // true 
    std::cout << std::is_same<decltype(b), uint16_t>::value << "\n"; // true 
} 

Thật không may, giải pháp mà không thể xử lý tách chữ số. Hơn nữa, máy móc std::conditional là khá xấu xí. Bạn có thể làm việc tốt hơn với boost::mpl::vector, boost::mpl::at và một số phép tính số học.

+0

Và bây giờ bỏ qua 0 hàng đầu trong loại khấu trừ;) Không có câu trả lời nghiêm túc, tốt. –

+2

@ChristianRau Thật dễ dàng để bỏ qua những người viết 0s. Hơn nữa, đó sẽ là ... nhị phân nhị phân! – Morwenn

+0

@Morwenn: Tôi muốn C và C++ không dùng hằng số chứa số 0 đứng đầu và không có gì khác với chữ số thập phân, * nhưng * xác định ký hiệu chuẩn cho hằng số bát phân theo kiểu thời trang mà mã có thể xác định macro (ví dụ __OCT (x)) macro sẽ giải thích x như một hằng số bát phân trong một trong hai kiểu trình biên dịch [ký hiệu ưa thích cá nhân của tôi, nhưng thực tế là nó sẽ mâu thuẫn với cú pháp chữ do người dùng xác định, có thể nói rằng 8x1234 sẽ là một hằng số bát phân, 0x1234 và 16x1234 sẽ là hex, 10x0sẽ là số thập phân, v.v. Điều đó có thể đã khái quát một cách độc đáo. – supercat

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