假设我的应用程序中需要一个新类型,它由一个std::vector<int>扩展的单个函数组成.直接的方式是组合(由于STL容器的继承限制):
class A {
public:
A(std::vector<int> & vec) : vec_(vec) {}
int hash();
private:
std::vector<int> vec_
}
Run Code Online (Sandbox Code Playgroud)
这要求用户首先在构造函数中构造一个vector<int>和一个副本,这在我们要处理大量的大向量时是不好的.当然,人们可以写一个传递push_back(),但这引入了可变状态,我想避免.
所以在我看来,我们可以避免复制或保持不可变,这是正确的吗?
如果是这样,最简单(和效率等效)的方法是在命名空间范围内使用typedef和free函数:
namespace N {
typedef std::vector<int> A;
int a_hash(const A & a);
}
Run Code Online (Sandbox Code Playgroud)
这只是在某种程度上感觉不对,因为未来的扩展将"污染"命名空间.此外,调用a_hash(...)any vector<int>是可能的,这可能会导致意外的结果(假设我们对用户必须遵循的A施加约束或者在第一个示例中强制执行)
我的两个问题是:
谢谢!
散列是一种算法而非类型,并且可能不应限于任何特定容器类型中的数据.如果你想提供散列,最有意义的是创建一个函数来计算一个哈希值元素(int就像你上面写的那样),然后使用std::accumulate或std::for_each将它应用于集合:
namespace whatever {
struct hasher {
int current_hash;
public:
hasher() : current_hash(0x1234) {}
// incredibly simplistic hash: just XOR the values together.
operator()(int new_val) { current_hash ^= new_val; }
operator int() { return current_hash; }
};
}
int hash = std::for_each(coll.begin(), coll.end(), whatever::hasher());
Run Code Online (Sandbox Code Playgroud)
请注意,这允许coll是a vector,或者deque你可以使用一对istream_iterators来散列文件中的数据...