Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to use long double for user defined literals? [duplicate]

Tags:

The following user defined literal omits an error:

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

but if long is added the error will disappear and code will work as follows:

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

the error is:

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

The problem is only caused by the argument and return type can be double without long.

Why is long needed?

like image 661
Sameh K. Mohamed Avatar asked May 01 '15 08:05

Sameh K. Mohamed


People also ask

What are user defined literals?

Similarly, User-Defined Literals (UDL) provides literals for a variety of built-in types that are limited to integer, character, floating-point, string, boolean, and pointer. In simple terms, they combine values with units. Examples of literal for built-in types: // Examples of classical literals for built-in types.

What are literals C++?

C++ Literals. Literals are data used for representing fixed values. They can be used directly in the code. For example: 1 , 2.5 , 'c' etc. Here, 1 , 2.5 and 'c' are literals.


2 Answers

C++11 draft n3290 has this to say about the parameters that user-defined literals can take (§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

As you can see, double is not in that list, only long double is. So you have to use that for user-defined literals that expect a floating point number as an argument.

like image 97
Mat Avatar answered Sep 29 '22 06:09

Mat


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.

From cpp reference: http://en.cppreference.com/w/cpp/language/user_literal

like image 36
Mohamed abd elrazek Avatar answered Sep 29 '22 05:09

Mohamed abd elrazek