В чем преимущество max_digits10, равного 0 для ссылок на типы с плавающей запятой? - PullRequest
3 голосов
/ 07 марта 2019

В C ++ 11, в чем преимущество std::numeric_limits<Type>::max_digits10, возвращающего 0 для Type, который является ссылкой на число с плавающей запятой?

Например:

constexpr int precisionPositive(const float &floatVal)
{
  using numericType    = std::remove_reference<decltype(floatVal)>::type;
  constexpr int digits = std::numeric_limits<numericType>::max_digits10;

  return digits;
}

constexpr int precisionZero(const float &floatVal)
{
  using numericType    = decltype(floatVal);
  constexpr int digits = std::numeric_limits<numericType>::max_digits10;

  return digits;
}

precisionPositive возвращает 9, а precisionZero возвращает 0.

При каких обстоятельствах полезно нулевое значение, а не ошибка времени компиляции?

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Согласно стандарту C ++ (n4659), в шаблоне класса numeric_limits значением по умолчанию для max_digits10 является 0.

21.3.4 Шаблон класса numeric_limits [numeric.limits]

namespace std {
template<class T> class numeric_limits {
public:
...  
static constexpr int max_digits10 = 0;

И только в том случае, если шаблон специализирован для float, double и т. Д., max_digits10 задается конкретное значение.

Рассмотрим специализацию для float.

21.3.4.2 numeric_limits specializations [numeric.special]

namespace std {
template<> class numeric_limits<float> {
public:
...
static constexpr int max_digits10 = 9;

Реализации также следуют этому.См., Например, стандартный заголовок библиотеки C ++ библиотеки GCC limit .

Так, за исключением специализаций, где max_digits10 задано определенное значение, значением по умолчанию является 0 и , поэтомузначение max_digits10 для ссылок на типы с плавающей запятой также 0.

0 голосов
/ 07 марта 2019

У меня нет правильного ответа на вопрос «почему».Купить Я мог бы использовать этот код:

C ++ 11:

template<typename T>
    using bare_value_t=typename
        std::decay<T>::type;

C ++ 14:

template<typename T>
    using bare_value_t=
        std::decay_t<T>;

C ++ 20:

template<typename T>
    using bare_value_t=
        std::remove_cvref_t<T>;

А:

template<typename T>
    using limits=
        std::numeric_limits<bare_value_t<T> >;

cout<<limits<float&>::max_digits10;
...