2015-05-01 19 views
17

Người dùng sau được định nghĩa theo nghĩa đen bỏ qua một lỗi:Tại sao tôi phải sử dụng số liệu dài gấp đôi cho các chữ số do người dùng xác định?

constexpr double operator "" _kg(double q) 
{ 
    return q*1000; 
} 

nhưng nếu long được thêm các lỗi sẽ biến mất và mã sẽ làm việc như sau:

constexpr double operator "" _kg(long double q) 
{ 
    return q*1000; 
} 

lỗi là:

‘constexpr double operator""_kg(double)’ has invalid argument list 

Vấn đề chỉ do đối số và kiểu trả về có thể là double mà không cần long.

Tại sao cần long?

+1

'long double' là một loại có độ chính xác cao hơn' double'., Giống như 'long int' là một biến thể lớn hơn' int'. –

+1

Đối với vấn đề của bạn, * bạn nhận được lỗi nào? Vui lòng chỉnh sửa câu hỏi của bạn để bao gồm đầu ra lỗi hoàn chỉnh và chưa được chỉnh sửa, * và * a [Ví dụ tối thiểu, hoàn chỉnh và có thể xác minh] (http://stackoverflow.com/help/mcve) gây ra lỗi. –

+0

Tôi đã chỉnh sửa câu hỏi để biết thêm chi tiết, bao gồm cả thông báo lỗi. –

Trả lời

21

C++ 11 dự thảo n3290 có này để nói về các thông số mà literals người dùng định nghĩa có thể mất (§13.5.8):

The declaration of a literal operator shall have a parameter-declaration-clause equivalent to one of the following:

const char* 
unsigned long long int 
long double 
char 
wchar_t 
char16_t 
char32_t 
const char*, std::size_t 
const wchar_t*, std::size_t 
const char16_t*, std::size_t 
const char32_t*, std::size_t 

Như bạn có thể thấy, double không có trong danh sách đó, chỉ long double là. Vì vậy, bạn phải sử dụng nó cho các chữ cái do người dùng định nghĩa, mong đợi một số dấu phẩy động làm đối số.

+0

Bất kỳ ý tưởng nào về lý do tại sao? – nbubis

+0

Không thực sự. Tôi đoán họ chỉ cần đi cho loại lớn nhất được đảm bảo để tồn tại bởi các tiêu chuẩn cho các văn học nấu chín. Nếu bạn cần nhiều hơn, bạn luôn có thể sử dụng các chữ gốc. Nếu bạn cần ít hơn, tốt, chỉ cần cắt ngắn. – Mat

+0

Tôi đoán lý do là cho một chữ, bạn không thể biết chính xác. Ví dụ, một số con số có một đại diện dài vô hạn trong định dạng dấu chấm động và do đó cần phải được cắt ngắn. Nó làm cho tinh thần không sớm cắt ngắn các literals hơn cần thiết. – danijar

3

Only the following parameter lists are allowed on literal operators :

  • (const char *) (1)
  • (unsigned long long int) (2)
  • (long double) (3)
  • (char) (4)
  • (wchar_t) (5)
  • (char16_t) (6)
  • (char32_t) (7)
  • (const char * , std::size_t) (8)
  • (const wchar_t * , std::size_t) (9)
  • (const char16_t * , std::size_t) (10) (const char32_t * , std::size_t) (11)

    1. Literal operators with this parameter list are the raw literal operators, used as fallbacks for integer and floating-point user-defined literals (see above)

    2. Literal operators with these parameter lists are the first-choice literal operator for user-defined integer literals

    3. Literal operators with these parameter lists are the first-choice literal operator for user-defined floating-point literals

4-7. Literal operators with these parameter lists are called by

user-defined character literals

8-11. Literal operators with these parameter lists are called by user-defined string literals

Default arguments are not allowed C language linkage is not allowed Other than the restrictions above, literal operators and literal operator templates are normal functions (and function templates), they can be declared inline or constexpr, they may have internal or external linkage, they can be called explicitly, their addresses can be taken, etc.

Từ tài liệu tham khảo cpp: http://en.cppreference.com/w/cpp/language/user_literal

0

Mặc dù sự thất bại của ANSI C để xác định một hình thức khai báo biến đối số mà sạch sẽ có thể xử lý một mở rộng có độ chính xác long double loại có định dạng khác với từ double đã dẫn đối với loại được sử dụng hiệu quả trên nhiều nền tảng (không may, IMHO, vì nó là loại tốt để sử dụng không chỉ trên các hệ thống có bộ xử lý x87 mà còn trên các hệ thống không có FPU), cách duy nhất cho một hệ thống có mở rộng phù hợp các loại -precision để xử lý một tuyên bố như:

long double a = 0.1; 

là phải có 0,1 số cuộc sống bắt đầu đen như một long double bằng 14,757,395,258,967,641,293/147,573,952,589,676,412,928; sẽ là vô lý khi có tuyên bố đó đặt a thành 7,205,759,403,792,794/72,057,594,037,927,936 (khoảng 0.10000000000000000555, giá trị của (double)0.1). Có thể được cho là một vài trường hợp có thời gian bắt đầu bằng chữ số là long double trước khi chuyển đổi xuống có thể khiến giá trị khác với giá trị nếu nó bắt đầu bằng double hoặc float (ví dụ: gần nhất là float đến 9007199791611905.0 là 9007200328482816, cao hơn giá trị được yêu cầu 536870911, nhưng (float)(double)9007199791611905.0 sản lượng 9007199254740992, là 536870913 dưới giá trị đó. những gì người ta thực sự muốn.

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