c++ 为什么我必须对用户定义的文本使用long double?[duplicate]

wtlkbnrh  于 2023-02-06  发布在  其他
关注(0)|答案(4)|浏览(107)
    • 此问题在此处已有答案**:

C++11 operator"" with double parameter(2个答案)
三年前关闭了。
以下用户定义的文本发出错误:

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

但如果添加了long,则错误将消失,代码将按如下方式工作:

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

错误为:

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

此问题仅由参数引起,并且返回类型可以是double而不包含long
为什么需要long

lyfkaqu1

lyfkaqu11#

C++11 draft n3290对用户定义的常量可以带的参数有如下说明(§13.5.8):
文字运算符的声明应包含等效于以下内容之一的 parameter-declaration-clause

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

如您所见,double不在该列表中,只有long double在,因此您必须对期望浮点数作为参数的用户定义文本使用该列表。

bbmckpt7

bbmckpt72#

文字运算符上只允许使用以下参数列表:

  • (常数字符 *)(1)
  • (无符号长整型长整型)(2)
  • (长双)(3)
  • (char)(四)
  • (w字符_t)(5)
  • (第16章_t)(6)
  • (第32章_t)(7)
  • (常量字符 *,标准::大小_t)(8)
  • (常量wchar_t *,标准::大小_t)(9)

1.(常量字符16_t *,标准::大小_t)(10)(常量字符32_t *,标准::大小_t)(11)
1.带有此参数列表的文本操作符是原始文本操作符,用作整数和浮点用户定义文本的后备(见上文)
1.具有这些参数列表的文本运算符是用户定义的整数文本的首选文本运算符
1.具有这些参数列表的文本运算符是用户定义浮点文本的首选文本运算符
4-7.具有这些参数列表的文本运算符由
用户定义字符文字
8-11。具有这些参数列表的文字运算符由用户定义的字符串文字调用
不允许默认参数不允许C语言链接除了上述限制之外,文字运算符和文字运算符模板是普通函数(和函数模板),它们可以声明为内联或constexpr,它们可以有内部或外部链接,它们可以被显式调用,它们的地址可以被获取,等等。
来自cpp参考:http://en.cppreference.com/w/cpp/language/user_literal

j1dl9f46

j1dl9f463#

Stroustrup有一个关于字符串常量的很棒的部分,他在那里声明(来自规范):

  • 浮点文字:由带有单个long double或const char* 参数的文本运算符接受。

http://www.stroustrup.com/C++11FAQ.html#UD-literals

t40tm48m

t40tm48m4#

尽管ANSI C未能定义一种形式的变量参数声明来清晰地处理扩展精度long double类型(其格式不同于double),但这已导致该类型在许多平台上实际上已被弃用(不幸的是,恕我直言,因为它是一个很好的类型,不仅适用于有x87协处理器 * 的系统,而且适用于没有FPU* 的系统),这是具有适当扩展精度类型的系统处理如下语句的唯一合理方法:

long double a = 0.1;

具有0.1的数字文字起始寿命,如long double等于14,757,395,258,967,641,293/147,573,952,589,676,412,928;让语句将a设置为7,205,759,403,792,794/72,057,594,037,927,936(大约为0.1000000000000000555,(double)0.1值)是荒谬的。
可能有争议的是,在得到下转换之前具有作为long double的数字文本开始生命可能导致它产生与如果它作为doublefloat开始生命时不同的值(例如,最接近9007199791611905.0float是9007200328482816,其比请求值高536870911,但是(float)(double)9007199791611905.0产生9007199254740992,其比请求值低536870913。当然,如果需要浮点值9007200328482816.0f,则可能应该使用更接近于实际需要的十进制表示。

相关问题