简体   繁体   English

为什么数字10用于引用整数类型0?

[英]Why is digits10 for reference to integer type 0?

The following code: 以下代码:

#include <iostream>
#include <limits>
#include <cstdint>

int main() 
{
    std::cout << std::numeric_limits<std::uint64_t>::digits10 << "\n" 
              << std::numeric_limits<std::uint64_t&>::digits10 << "\n";
}

outputs 输出

19 19
0 0

I would expect std::uint64_t& to have same value as std::uint64_t : Is there a reason for this discrepancy? 我希望std::uint64_t&有相同的值std::uint64_t :有没有这种差异的一个原因?

18.3.2.1/2: 18.3.2.1/2:

Specializations shall be provided for each arithmetic type, both floating point and integer, including bool. 应为每种算术类型提供专业化,包括浮点和整数,包括bool。 The member is_specialized shall be true for all such specializations of numeric_limits. 对于numeric_limits的所有此类特化,成员is_specialized应为true。

So we know that specializations will exist for for these non-reference types. 因此,我们知道对于这些非引用类型将存在特化。 Then 18.3.2.3/1: 那么18.3.2.3/1:

The default numeric_limits template shall have all members, but with 0 or false values. 默认的numeric_limits模板应包含所有成员,但具有0或false值。

I suspect it was done this way because you can always static_assert on is_specialized to force a compile error, but there could possibly be some template application where 0 would be an ok default value for one or more of the limits. 我怀疑它是以这种方式完成的,因为你总是可以在is_specialized上使用static_assert来强制编译错误,但是可能会有一些模板应用程序,其中0对于一个或多个限制来说是一个ok的默认值。 If you want to be able to test references just run it through std::remove_reference . 如果您希望能够测试引用,只需通过std::remove_reference运行它。

I'm not sure if it's legal to specialize numeric_limits for your own types. 我不确定将numeric_limits专门用于你自己的类型是否合法。 The standard in 18.3.2.1/4 says: 18.3.2.1/4中的标准说:

Non-arithmetic standard types, such as complex (26.4.2), shall not have specializations. 非算术标准类型,例如complex(26.4.2),不应具有特化。

I personally read this qute as "the standard will not provide specializations for non-arithmetic standard libray types, but it's perfectly legal to specialize for a user type". 我个人认为这个问题是“标准不会为非算术标准库类型提供专业化,但专门针对用户类型是完全合法的”。 You could just as easily read this as totally forbidding any non-provided specializations. 您可以轻松地将其视为完全禁止任何未提供的专业化。

The type uint64& is a reference, so it's not one of the arithmetic types that the numeric_limits template should be used for. 类型uint64&是一个引用,因此它不是numeric_limits模板应该用于的算术类型之一。

For any other types than the arithmetic types defined, the default definition is used which contains: 对于除定义的算术类型之外的任何其他类型,使用默认定义,其中包含:

static const int  digits10 = 0;

Reference: http://www.cplusplus.com/reference/limits/numeric_limits/ 参考: http//www.cplusplus.com/reference/limits/numeric_limits/

std::numeric_limits is expected to be specialized for fundamental arithmetic data types (integers and floating points). std::numeric_limits应该专门用于基本算术数据类型(整数和浮点)。 A reference -of any kind- does not belong to them and that's why the non-specialized template is chosen, which has all its members to false ( 0 ). 任何类型的引用都不属于它们,这就是为什么选择非专用模板,其所有成员都为false0 )。

I would expect std::uint64_t& to have same value as std::uint64_t: Is there a reason for this discrepancy? 我希望std :: uint64_t&与std :: uint64_t具有相同的值:这是否存在这种差异的原因?

Although std::uint64_t is an arithmetic type, std::uint64_t& is a compound type and has a different meaning. 虽然std::uint64_t是算术类型,但std::uint64_t&是一种复合类型,具有不同的含义。 You have a few options: 你有几个选择:

  • Always consider the base type by removing the reference, pointer or both. 始终通过删除引用,指针或两者来考虑基本类型。
  • static_assert( is_arithmetic<> )
  • check std::numeric_limits<T>::is_specialized 检查std::numeric_limits<T>::is_specialized

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM