我创建了一个无序集合,并定义了哈希函数。
struct pair_hash
{
template<typename Ta, typename Tb>
std::size_t operator() (std::pair<Ta, Tb> const& pair) const
{
std::size_t h1 = std::hash<Ta>()(pair.first);
std::size_t h2 = std::hash<Tb>()(pair.second);
return h1 ^ h2;
}
};
我可以用以下方法创建这个集合:
std::unordered_set<std::pair<Atom*, Atom*>, pair_hash> bonds;
我也可以用... 把值插入到集合中去
bonds.insert(bond);
这一切都很好,但是我在尝试寻找集合中的元素时遇到了问题。当我尝试使用:时,我得到了 "Term does not evaluate to a function taking 1 arguments "的错误信息。
std::pair<Atom*, Atom*> bond = std::make_pair(atom_a, atom_b);
if (bonds.find(bond) == bonds.end())
{
//Unbonded
}
else
{
//Bonded
}
如果有任何帮助,我将非常感激! 以下是我的代码,供参考。
#include <iostream>
#include <vector>
#include <unordered_set>
#include <fstream>
#include <string>
#include <sstream>
#include <utility>
struct Vector3
{
float x;
float y;
float z;
Vector3(float x, float y, float z) :
x(x),
y(y),
z(z)
{}
};
struct Atom
{
int atomic_number;
Vector3 position;
Vector3 velocity;
Atom(int atomic_number, Vector3 position, Vector3 velocity = Vector3(0.0f, 0.0f, 0.0f)) :
atomic_number(atomic_number),
position(position),
velocity(velocity)
{}
};
std::vector<std::string> SplitString(const std::string& str, char delim)
{
std::vector<std::string> out;
std::stringstream curr;
for (char c : str)
{
if (c == delim)
{
out.emplace_back(curr.str());
curr.str("");
}
else
{
curr << c;
}
}
out.emplace_back(curr.str());
return out;
}
struct pair_hash
{
template<typename Ta, typename Tb>
std::size_t operator() (std::pair<Ta, Tb> const& pair) const
{
std::size_t h1 = std::hash<Ta>()(pair.first);
std::size_t h2 = std::hash<Tb>()(pair.second);
return h1 ^ h2;
}
};
void LoadEnvironment(const char* file_name, std::vector<Atom*>& particles, std::unordered_set<std::pair<Atom*, Atom*>, pair_hash>& bonds)
{
std::ifstream file(file_name);
std::stringstream ss;
ss << file.rdbuf();
std::string data = ss.str();
std::vector<std::string> molecule_strings = SplitString(data, '|');
for (const std::string& molecule_string : molecule_strings)
{
std::vector<std::string> molecule_attributes = SplitString(molecule_string, '#');
std::string& atom_data = molecule_attributes[0];
std::string& bond_data = molecule_attributes[1];
std::vector<std::string> atom_strings = SplitString(atom_data, '/');
std::vector<std::string> bond_strings = SplitString(bond_data, '/');
std::vector<Atom*> molecule_atoms;
std::vector<std::pair<Atom*, Atom*>> molecule_bonds;
for (const std::string& atom_string : atom_strings)
{
std::vector<std::string> atom_value_strings = SplitString(atom_string, ',');
std::vector<float> atom_values;
for (const std::string& atom_value_string : atom_value_strings)
{
float value = stof(atom_value_string);
atom_values.push_back(value);
}
int atomic_number = static_cast<int>(atom_values[0]);
Vector3 position(atom_values[1], atom_values[2], atom_values[3]);
Vector3 velocity(atom_values[4], atom_values[5], atom_values[6]);
Atom* atom = new Atom(atomic_number, position, velocity);
molecule_atoms.push_back(atom);
}
for (const std::string& bond_string : bond_strings)
{
std::vector<std::string> bond_atoms = SplitString(bond_string, ',');
int atom_a_index = stoi(bond_atoms[0]);
int atom_b_index = stoi(bond_atoms[1]);
Atom* atom_a = molecule_atoms[atom_a_index];
Atom* atom_b = molecule_atoms[atom_b_index];
molecule_bonds.emplace_back(atom_a, atom_b);
}
for (Atom* atom : molecule_atoms)
{
particles.push_back(atom);
}
for (std::pair<Atom*, Atom*> bond : molecule_bonds)
{
bonds.insert(bond);
}
}
}
void TimeStep(std::vector<Atom*>& atoms, const std::unordered_set<std::pair<Atom*, Atom*>> bonds)
{
for (Atom* atom_a : atoms)
{
for (Atom* atom_b : atoms)
{
if (atom_a == atom_b) continue;
std::pair<Atom*, Atom*> bond = std::make_pair(atom_a, atom_b);
if (bonds.find(bond) == bonds.end())
{
//Unbonded
}
else
{
//Bonded
}
}
}
}
int main()
{
std::vector<Atom*> particles;
std::unordered_set<std::pair<Atom*, Atom*>, pair_hash> bonds;
LoadEnvironment("simulation.txt", particles, bonds);
return 0;
}
你忘了模板参数 pair_hash
在
void TimeStep(std::vector<Atom*>& atoms, const std::unordered_set<std::pair<Atom*, Atom*>> bonds)
应该是
void TimeStep(std::vector<Atom*>& atoms, const std::unordered_set<std::pair<Atom*, Atom*>, pair_hash> bonds)
没有它 std::hash
将会使用,这不是专门用于 std::pair
,即 std::hash<std::pair<X, Y>>
不存在,从而导致错误。