Оцените полиморфные c объекты во время компиляции - PullRequest
0 голосов
/ 24 апреля 2020

Проблема

Я пытаюсь создать тип Precision для строго типизированного интерфейса. Тем не менее, я не могу заставить его оценить во время компиляции. Есть ли что-то, что мне не хватает?

Код

#include <cstdint>

constexpr uint8_t DOUBLE_MAX_PRECISION{ 16 };
constexpr uint8_t FLOAT_MAX_PRECISION {  7 };

template<uint8_t max>
struct BoundType
{
    constexpr BoundType(uint8_t value) : value{ value }
    {
       if(value > max) {
           value = max;
       }
    }

    const uint8_t value;
};

template <typename T> struct Precision {};

template<> 
struct Precision<double> : public BoundType<DOUBLE_MAX_PRECISION>
{
   constexpr Precision(uint8_t value) : BoundType(value) {}
};

template<>
struct Precision<float> : public BoundType<FLOAT_MAX_PRECISION>
{
    constexpr Precision(uint8_t value) : BoundType(value) {}
};

Вариант использования

void print(double number, const Precision<double>&& precision)
{
    uint8_t prec = precision.value;

    //use prec here to print the numbers decimal digits
}

void print(float number, const Precision<float>&& precision)
{
    uint8_t prec = precision.value;

    //use prec here to print the numbers decimal digits
}

int main()
{
    print(10.0, Precision<double>(10));
    print(10.0, Precision<float>(5));
    return 0;
}

Годовая стрела: https://godbolt.org/z/FRRBtW

Редактировать

После прочтения ваших предложений я пришел к решению, которое оценивает во время компиляции! Я использовал godbolt под x86-64 g cc (транк) с флагом -Os и некоторыми незначительными изменениями кода.

Я делюсь кодом не только для помощи нуждающимся, но и для людей, чтобы изменить и предложить лучшие решения в этой теме.

Годболт ссылка: https://godbolt.org/z/Q8Q3L4

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Вам необходимо использовать ваше значение в контексте constexpr, хотя в целом оно все еще не гарантирует оценку времени компиляции (для этого c ++ 20 добавлено consteval), но на практике обычно достаточно назначить значение, которое вы хотите, чтобы время компиляции вычислялось в переменную constexpr, то есть:

int main()
{
    constexpr auto foo = Precision<double>(10);
    print(10.0, foo); // change the signature to const ref
    return 0;
}

Кроме того, вы компилируете без оптимизации, что также может способствовать нежеланию компилятора делать больше, чем необходимо .

0 голосов
/ 24 апреля 2020

Разве функция печати не должна быть constexpr для оценки во время компиляции?

...