在编译时评估多态对象。

问题描述 投票:0回答:1

问题

我试图为一个强类型接口创建一个 "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;
}

Godbolt链接。https:/godbolt.orgzFRRBtW

编辑

在阅读了您的建议后,我想出了一个在编译时进行评估的解决方案!我在x86-64的gcc(trunk)下使用godbolt,并使用-Os标志和一些小的代码修改。我在x86-64 gcc (trunk)下使用了godbolt,并使用了-Os标志和一些小的代码修改。

我把代码分享出来,不仅是为了帮助那些需要帮助的人,也是为了让大家在这个帖子里修改并提出更好的解决方案。

Godbolt链接。https:/godbolt.orgzQ8Q3L4

c++ embedded metaprogramming
1个回答
1
投票

你需要用你的价值在 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;
}

另外,你在编译时没有进行优化 也可能导致编译器不愿意做更多的优化工作


-1
投票

打印函数是不是应该是 constexpr 要在编译时进行评估?

© www.soinside.com 2019 - 2024. All rights reserved.