(更新:此问题源于对const Foo
和Foo
具有不同含义的对象的值传递的包装类的实现,基于移动{ {3}}。之前,我一直在传递const Foo*
和Foo*
,当包装器出现时我换了Wrapper<Foo>
和const Wrapper<Foo>
。它现在很清楚,机械替换没有意义,我将需要更复杂的东西,例如Wrapper<Foo>
和Wrapper<const Foo>
......虽然我不知道怎么写得恰到好处对于误解的道歉,但我会把它保留在这里,因为我认为它比许多问题更具启发性。)
在研究entirely on strong opinions from people here时,似乎可以归结为与你无法做到这一点的想法并列:
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...
似乎(根据我的理解)this question可以在参考案例中解决这个问题,例如:
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访问该树中的节点,其中将前一节点传递给函数是如何获得新节点)
如果您想变得笨重,可以使用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
”版本之外,还有更好的解决方法吗?
答案 0 :(得分:2)
如果我在这里忽视某些事情,我表示道歉。但既然你的问题没有提到它,我想知道你是否意识到,并考虑过:
Foo defaultFoo (6502);
std::reference_wrapper<const Foo> theFooRef (getFooRef());
if (theFooRef.get().getBar() < 2000) {
theFooRef = std::cref(defaultFoo);
}
// ...do stuff with theFooRef.get() or employ implicit cast...
答案 1 :(得分:1)
如果你想变得笨重,你可以使用std :: pair而忽略bool:
这清楚地解释了为什么你想做的事情无法完成,因为this code doesn't work.我使用了const int
而不是const Foo
,但这是一样的想法。这条线是它破裂的地方:
theFooBool = std::pair<const Foo, bool> (defaultFoo, false);
复制赋值运算符未声明为const
,因为根据定义,复制赋值是更改对象。当您希望对象不可更改时,const
就是您使用的。
当然,您可以使用std::reference_wrapper<const T>
,它将为您提供const
访问权限,但允许重新绑定。当然,它没有提供价值语义,但是它就像你将要获得的那样接近。一般来说,大多数人不需要甚至不需要这样,所以它还没有出现。