考虑到我有一个特殊的类A
,它带有一些有用的强类型枚举类型:
/* from A.hpp */
enum class A_type {
A1,
A2,
A3,
A4,
/* ... */
A47
}
static const N_A_type = 47;
class A {
public:
A();
/* some other stuff */
};
现在考虑一下我有另一个类,它包装着A
指针的向量,需要跟踪成员容器中对象的类型,例如用于元素访问和类型检查:
class B {
public:
B(const std::vector<std::shared_ptr<A>>& _ptrs, const std::vector<A_type> _types) : ptrs(_ptrs), types(_types) { /**/ };
/* ... */
// element acessors w/ const overload
std::shared_ptr<A> operator[](const A_type& _type) { /* */ }
std::shared_ptr<const A> operator[](const A_type& _type) const { /* */ }
// list types contained in B
std::vector<A_type> types() const;
// check if any element of specific A_type exists
bool hasType(const A_type& _type) const { /* */ }
/* ... */
protected:
std::vector<std::shared_ptr<A>> ptrs;
};
我正在寻找一种高效且“干净”的方法来跟踪B
中存在的类型。虽然我有几种方法,但是我认为这两种更快并且允许使用更简洁的语法的方法是添加B的受保护/私有成员:
使用与vector<A_type>
相同大小的ptrs
以及相应的类型,或者使用std::find
手动遍历向量来检查是否存在特定类型并返回其索引。这可能意味着必须(在构造函数中)确保两个向量都经过排序以便更快地搜索;
使用大小为vector<int>
(或N_A_type
)的array<int,N_A_type>
(将填充在构造函数中,并存储对应类型的索引,如果有的话),例如-1(如果不存在)。因此,访问/检查特定类型是将枚举类型强制转换为int
的问题,不需要向量搜索。
就个人而言,我更喜欢第一个,因为尽管它似乎不那么快速/高效,但界面更整洁,例如使用相同的构造函数返回B
的子集,而不会在具有大量冗余/不必要值的容器周围拖动。
但是在第二种方法上,std::find
到底会增加多少开销?