(更新:这个问题源于一个包装类的实现,该包装类通过值传递一个对象,该对象对const Foo
and具有不同的含义Foo
,这一举动完全基于这里人们的强烈意见。之前,我一直在传递const Foo*
和Foo*
当包装器来了,我把它换成了Wrapper<Foo>
and const Wrapper<Foo>
。 现在很明显,机械替换没有意义,我需要更复杂的东西,比如Wrapper<Foo>
and Wrapper<const Foo>
...虽然我不知道如何正确地写还没有。对造成的误解表示歉意,但我会在这里保留这个,因为我实际上认为它比许多问题更能说明问题。)
在调查这个问题时,它似乎归结为与你不能这样做的想法平行:
const Foo defaultFoo (6502);
const Foo theFoo (getConstFoo()); // returns const Foo for privilege reasons
if (theFoo.getBar() < 2012) {
theFoo = defaultFoo; // Error.
}
// ...you want to do const-safe methods with theFoo...
就像引用一样,一个 const 值不能被重新定位。执行以下操作会编译,但不是我(在这种情况下)想要的:
Foo defaultFoo (6502);
Foo& theFooRef (getFooRef());
if (theFooRef.getBar() < 2000) {
theFooRef = defaultFoo; // Not an error, but not a retarget.
}
// ...you want to do stuff with theFooRef...
似乎(根据我的理解)reference_wrapper
可以在参考案例中解决这个问题,例如:
Foo defaultFoo (6502);
std::reference_wrapper<Foo> theFooRef (getFooRef());
if (theFooRef.get().getBar() < 2000) {
theFooRef = std::ref(defaultFoo);
}
// ...do stuff with theFooRef.get() or employ implicit cast...
我想知道是否有一个“ value_wrapper
”在那里做类似的事情。出于 const 正确性的原因,想要一个按值保存项目的变量对我来说似乎是合理的……而不是因为您不打算更改它。 (例如在前序树遍历中跟踪当前节点,尽管只有 const 访问该树中的节点,其中将前一个节点传递给函数是获取新节点的方式)
如果你想变得笨重,你可以使用std::pair<const Foo, bool>
并忽略bool
:
const Foo defaultFoo (6502);
std::pair<const Foo, bool> theFooBool (getConstFoo(), false);
if (theFooBool.first.getBar() < 2012) {
theFooBool = std::pair<const Foo, bool> (defaultFoo, false);
}
// ...do const-safe methods with theFooBool.first...
但是,除了实现我自己的“”版本之外,还有更好的方法来解决这个问题value_wrapper
吗?