加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何在编译时检查查找表的大小是否正确?

发布时间:2020-12-16 10:04:40 所属栏目:百科 来源:网络整理
导读:我对 lookup table的值进行了硬编码.所需的元素数量来自一个包含的文件,该文件可能在将来的某个时候发生变化.所以我想在编译时确保我指定的元素数量确实与所需数量匹配. 看看这段代码: #include array// Assume this comes from some included fileconstexp
我对 lookup table的值进行了硬编码.所需的元素数量来自一个包含的文件,该文件可能在将来的某个时候发生变化.所以我想在编译时确保我指定的元素数量确实与所需数量匹配.

看看这段代码:

#include <array>

// Assume this comes from some included file
constexpr size_t elementCount = 5;

int main() {
    // This works.
    const std::array<int,elementCount> lookup { 2,4,6,8,10 };

    // But so does this.
    const std::array<int,elementCount> lookup2 { 2,6 };

    return 0;
}

std :: array似乎非常适合查找表,因为它的大小在编译时是固定的.但是,我无法确保使用正确数量的元素初始化它.由于aggregate initialization,即使我指定的元素太少,该示例也会编译好.

我提出了以下解决方法,但感觉非常难看:

#include <array>

template<class T> std::array<T,1> makeArray(T e1) {
    return { e1 };
}

template<class T> std::array<T,2> makeArray(T e1,T e2) {
    return { e1,e2 };
}

template<class T> std::array<T,3> makeArray(T e1,T e2,T e3) {
    return { e1,e2,e3 };
}

template<class T> std::array<T,4> makeArray(T e1,T e3,T e4) {
    return { e1,e3,e4 };
}

template<class T> std::array<T,5> makeArray(T e1,T e4,T e5) {
    return { e1,e4,e5 };
}

// ... and so on; these functions would live in some utility header file.

// Assume this comes from some included file
constexpr size_t elementCount = 5;

int main() {
    // This works.
    const std::array<int,elementCount> lookup = makeArray(2,10);

    // This doesn't. :-)
    const std::array<int,elementCount> lookup2 = makeArray(2,6);

    return 0;
}

所以问题是:是否有一种优雅的方法可以确保在编译时我为查找表指定正确数量的元素我是硬编码的?注意,数据类型不必是std :: array;任何以常量时间索引的序列容器都可以.

解决方法

您可以模拟make_array(类似于Library Fundamentals TS中的 make_array):

template<typename T,typename... Params>
std::array<T,sizeof...(Params)> make_array(Params&&... ps) {
    return { std::forward<Params>(ps)... };
}

现在,只需创建您的数组:

int main() {
    // This works.
    const auto lookup = makeArray<int>(2,10);
    static_assert(lookup.size() == elementCount,"");


    // This doesn't. :-)
    const auto lookup2 = makeArray<int>(2,6);
    static_assert(lookup2.size() == elementCount,""); // error
}

如果需要,可以将断言移动到make_array函数(或为其创建一个包装器),但是,可能会按顺序更改名称:

template<typename T,sizeof...(Params)> make_lookup_array(Params&&... ps) {
    static_assert(sizeof...(Params) == elementCount,"must be equal!");
    return { std::forward<Params>(ps)... };
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读