gpt4 book ai didi

c++ - 如何构建高效的命名数组?

转载 作者:行者123 更新时间:2023-12-02 05:06:59 25 4
gpt4 key购买 nike

我想要一种既具有命名成员又可迭代的类型,因此应该能够通过索引、标签或 for-each 循环引用成员。实现这一点的一种方法是使用 std::unordered_map<std::string,T>以及一些索引的辅助数据。显然,这会非常低效,因为对于每个成员访问,您都需要散列 std::string .

我当前的尝试如下所示:

// named-array.h
#pragma once

#include <array>
#include <cstddef>

#define NamedArray_KeyDecl(Name, ...) enum class Name : std::size_t { __VA_ARGS__, NUM }

namespace util {
template <typename K, typename T>
struct NamedArray {
static constexpr std::size_t cast(K k) {
return static_cast<std::size_t>(k);
}

std::array<T,cast(K::NUM)> array;
NamedArray(std::array<T,cast(K::NUM)> a) : array(a) {
}
constexpr T& operator[](K k) {
return array[cast(k)];
}
constexpr T const& operator[](K k) const {
return array[cast(k)];
}
};
}

可以像这样使用:

  struct Gadget {
int i;
Gadget(int i) : i(i) {}
void operator()() const {
std::cout << "Gadget(" << i << ")\n";
}
};

NamedArray_KeyDecl(Test1, a,b,c,d);

util::NamedArray<Test1,Gadget> gadgets {{0,1,2,3}};
// for each works:
for (auto const& gadget: gadgets.array) {
gadget();
}
// named access works:
gadgets[Test1::b]();
// access by index works:
gadgets.array[1]();

通过转发std::array的所有接口(interface)函数可以避免暴露数组成员。 .

但是,一个明显的缺点是

  1. gadgets[Test1::b]并不像 gadgets.member().b 那样漂亮和
  2. 有一个暴露的#define在 C++ 头文件中(非常臭)

有没有办法让命名数组具有与 std::array 相同的性能?

最佳答案

如何完成的简单示例:

#include <array>
#include <type_traits>

template<class Tag, class...Tags>
struct position {
};

template<class Tag, class...Tags>
struct position<Tag, Tag, Tags...> {
constexpr static unsigned value = 0;
};

template<class Tag, class First, class...Tags>
struct position<Tag, First, Tags...> {
constexpr static unsigned value = 1 + position<Tag, Tags...>::value;
};


template<class T, class...Tags>
class NamedArray {
public:

template<class U>
constexpr T& operator[](U tag) {
return array_[position<U, Tags...>::value];
}

constexpr T& operator[](unsigned val) {
return array_[val];
}

template<class U>
constexpr T& member(U u = U{}) {
return (*this)[u];
}
private:
std::array<T, sizeof...(Tags)> array_;
};

struct tag1{};
struct tag2{};

int main() {

NamedArray<int, tag1, tag2> a;
a[tag1{}];
a[tag2{}];

a.member(tag1{});
a.member<tag1>();

}

关于c++ - 如何构建高效的命名数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60315426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com