是否有类似std :: value_wrapper与std :: reference_wrapper并行的东西?

时间:2012-07-12 23:45:25

标签: c++ c++11 wrapper const-correctness reference-wrapper

更新:此问题源于对const FooFoo具有不同含义的对象的值传递的包装类的实现,基于移动{ {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”版本之外,还有更好的解决方法吗?

2 个答案:

答案 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访问权限,但允许重新绑定。当然,它没有提供价值语义,但是它就像你将要获得的那样接近。一般来说,大多数人不需要甚至不需要这样,所以它还没有出现。