我编写了一个表示大整数的模板类,如下所示:
template<typename ElementType, uint32_t ElementNum>
class Integer final{
//Some public function.
private:
ElementType value_[ElementNum];
};
我需要创建一个 Integer 类型的编译时常量
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
您能指导我如何修改这个 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;
}
您能指导我如何修改这个 Integer 类并构造这种类型的编译时常量吗?
这似乎是一个编译器错误。使此功能适用于所有编译器的解决方法是将
ElementType value_[ElementNum];
替换为 ElementType value_[ElementNum] = {};