对于嵌入式项目,我将帮助器类用于标志和掩码。由于未知的原因,掩码类的代码未按预期正确地正确折叠。

掩码的最小实现如下所示:

template<typename Enum, typename MaskValue>
class EnumMask
{
public:
    constexpr inline EnumMask() noexcept : _mask(0) {}
    constexpr inline EnumMask(Enum enumValue) noexcept : _mask(maskFromEnum(enumValue)) {}
    constexpr inline EnumMask(const std::initializer_list<Enum> enumValues) noexcept : _mask(maskFromEnum(enumValues.begin(), enumValues.end())) {}
    constexpr inline operator MaskValue() const noexcept { return _mask; }
private:
    constexpr static inline MaskValue maskFromEnum(const Enum enumValue) noexcept {
        return (static_cast<MaskValue>(1)<<static_cast<uint8_t>(enumValue));
    }
    constexpr static inline MaskValue maskFromEnum(
        typename std::initializer_list<Enum>::const_iterator it,
        typename std::initializer_list<Enum>::const_iterator end) noexcept
    {
        return (it == end ? static_cast<MaskValue>(0) : (maskFromEnum(*it)|maskFromEnum(it+1, end)));
    }
private:
    const MaskValue _mask;
};

该类的用法如以下示例所示:
class Driver
{
public:
    enum Pin : uint8_t {
        GPA0 = 0x00,
        GPA1 = 0x01,
        GPA2 = 0x02,
    };
    typedef EnumMask<Pin, uint16_t> PinMask;
    void setPinDirection(const uint16_t mask, bool direction);
    inline void setPinDirection(const PinMask &mask, bool direction) {
        setPinDirection(static_cast<uint16_t>(mask), direction);
    }
};

void main()
{
    Driver d;
    d.setPinDirection({Driver::GPA0, Driver::GPA1}, true);
}

该代码使用GCC 4.8.3和-Os选项进行编译。我希望编译器会将此代码解析为单个值,但实际上它创建了一个函数,用于根据这些值计算掩码。

我的代码中是否有特定的原因阻止了正确的const折叠?

最佳答案

解释实际上很简单:

从C++ 14开始,begin()end()std::initializer_list成员仅是constexpr

参见reference

关于c++ - 编译器不对掩蔽类进行固定折叠,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50310614/

10-11 22:50
查看更多