我有std::unordered_set
,其中包含类bar
的实例。
我希望迭代集合中的所有bar
,并在每个void foo(bar& b)
上调用一些foo
函数。
您可能会从功能签名中注意到我希望bar& b
以某种方式更改foo
参数的状态。
现在,我知道bar
以一种影响哈希或平等比较的方式不会改变const bar&
,但我仍然有问题。
然而,我迭代了这个集合,我所希望的最好的是const_cast
显然不会起作用。
我可以想到几种可能的方法:
std::unordered_map
。不知道这是否会起作用(还)。这对我来说有点难闻,但我很高兴能够开悟!! std::unordered_set
代替const
,即使我只能获得密钥的bar
,我也可以使用该密钥查找foo
对象并安全地呼叫 let mat = SCNMatrix4FromMat4(currentFrame.camera.transform)
let dir = SCNVector3(-1 * mat.m31, -1 * mat.m32, -1 * mat.m33)
let currentPosition = pointOfView.position + (dir * 0.1)
if button!.isHighlighted {
if let previousPoint = previousPoint {
let line = lineFrom(vector: previousPoint, toVector: currentPosition)
let lineNode = SCNNode(geometry: line)
lineNode.geometry?.firstMaterial?.diffuse.contents = lineColor
sceneView.scene.rootNode.addChildNode(lineNode)
}
}
。我真的很感激一些建议!
提前致谢!
答案 0 :(得分:1)
this answer已经显示了一些干净的解决方案。
另一种干净的方法是通过指针添加一个间接层。即使指针本身是const
,指向的数据也不会是:
struct Bar
{
int key;
std::unique_ptr<int> pValue;
};
std::unordered_set< Bar, BarHash, BarEqual > bars;
for( const auto& bar : bars )
{
// Works because only the pointer is constant, not the data pointed to.
*bar.pValue = 42;
}
这显然有额外内存分配的开销,存储指针所需的空间以及通过指针访问值时的间接。
如果要保留值语义,您还必须编写自定义复制构造函数和赋值运算符。
答案 1 :(得分:0)
使用
const_cast
。不知道这是否会起作用(还)。这对我来说有点难闻,但我很高兴能够开悟!!
是的,它会起作用。您可以轻松地重载foo(bar const&)
,const_cast
引用,然后调用foo(bar&)
。我同意你的看法,它闻起来很糟糕,并指出设计存在缺陷。您可能需要重新审视设计,看看是否有一个干净的解决方案。
使用
std::unordered_map
代替std::unordered_set
,这样即使我只能获得密钥的const,我也可以使用该密钥查找bar对象并安全地调用foo < / p>
这与第一种方法没有什么不同。 std::unordered_set<T>
基本上是std::unordered_map<T, bool>
。
潜在的清洁解决方案:
从集合中获取对象的副本,从集合中删除条目,更新副本,然后将副本放回集合中。如果证明太贵了......
使用std::vector<Bar>
。你可以从矢量中得到一个Bar&
,一切都很好。
将不会影响其哈希值的Bar
成员变量设为mutable
。然后,您可以使用foo(Bar const&)
并使用对集合中对象的引用直接调用它。