如何使用初始化列表初始化 constexpr 类?

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

我编写了一个表示大整数的模板类,如下所示:

template<typename ElementType, uint32_t ElementNum>
class Integer final{
    //Some public function.
private:
    ElementType value_[ElementNum];
};

我需要创建一个 Integer 类型的编译时常量。为了实现这一点,我添加了各种 constexpr 构造函数,但使用其中任何一个都会导致编译错误。

template<typename ElementType, uint32_t ElementNum>
class Integer final{
public:
    constexpr Integer(const std::initializer_list<ElementType> &l){
        auto iter = l.begin();
        for (uint32_t i = 0; i < ElementNum; i++) {
            if (iter != l.end()) {
                value_[i] = *iter;
                iter++;
            } else {
                value_[i] = 0;
            }
        }
    };
    constexpr Integer(const std::array<ElementType, ElementNum> &v){
        for (uint32_t i = 0; i < ElementNum; i++) {
            value_[i] = v[i];
        }
    };
    constexpr explicit Integer(const ElementType data[ElementNum]){
        for (uint32_t i = 0; i < ElementNum; i++) {
            value_[i] = data[i];
        }
    };
private:
    ElementType value_[ElementNum];
};
int main() {
    //error: expression must have a constant value
    //constexpr Integer<uint32_t, 2> a({1, 2});
    //                                 ^
    //note #2703-D: cannot call non-constexpr function "Integer<ElementType, ElementNum>::Integer(const std::initializer_list<ElementType> &) [with ElementType=uint32_t, ElementNum=2U]" 
    //constexpr Integer<uint32_t, 2> a({1, 2});
    //                                 ^
    constexpr Integer<uint32_t, 2> a({1, 2});
    constexpr std::array<uint32_t, 2> t({1,2});
    //error: expression must have a constant value
    //constexpr Integer<uint32_t, 2> b(t);
    //                                 ^
    //note #2703-D: cannot call non-constexpr function "Integer<ElementType, ElementNum>::Integer(const std::array<ElementType, ElementNum> &) [with ElementType=uint32_t, ElementNum=2U]"
    //constexpr Integer<uint32_t, 2> b(t);
    //                                 ^
    constexpr Integer<uint32_t, 2> b(t);
    constexpr uint32_t p[2] = {1,2};
    //error: expression must have a constant value
    //constexpr Integer<uint32_t, 2> c(p);
    //                                 ^
    //note #2703-D: cannot call non-constexpr function "Integer<ElementType, ElementNum>::Integer(const ElementType *) [with ElementType=uint32_t, ElementNum=2U]"
    //constexpr Integer<uint32_t, 2> c(p);
    //                                 ^
    constexpr Integer<uint32_t, 2> c(p);
    return 0;
}

您能指导我如何修改这个 Integer 类并构造这种类型的编译时常量吗?

编译器:gcc 9.4.0 C++ 标准:14

c++ constexpr
2个回答
0
投票

您能指导我如何修改这个 Integer 类并构造这种类型的编译时常量吗?

语言本身可以帮助你。你想做的事已经完成了,而且做得很好。例如,它已经为

std::array
完成,让我们利用它:

#include <utility>
#include <array>
#include <cstdlib>

template<typename ElementType, std::size_t ElementNum>
class Integer final{
public:
    template<class... T>
    constexpr Integer(T... values)
        : value_{ std::forward<ElementType>(values)... }
    {}
private:
    std::array<ElementType, ElementNum> value_;
};

#include <cstdint>
int main()
{
    constexpr Integer<std::uint32_t, 2> integer{1, 2};
    (void) integer;
}

编译器资源管理器演示


0
投票

您能指导我如何修改这个 Integer 类并构造这种类型的编译时常量吗?

这似乎是一个编译器错误。使此功能适用于所有编译器的解决方法是将

ElementType value_[ElementNum];
替换为
ElementType value_[ElementNum] = {};

演示

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