有没有类似std::value_wrapper的东西与std::reference_wrapper并行

Is there anything like a std::value_wrapper parallel to std::reference_wrapper?

本文关键字:wrapper std reference 并行 value 有没有      更新时间:2023-10-16

UPDATE:这个问题源于一个包装类的实现,该包装类通过对象的值传递,该对象对const FooFoo具有不同的含义,这一举动完全基于这里的人的强烈意见。以前,我一直在传递const Foo*Foo*,当包装出现时,我将其替换为Wrapper<Foo>const Wrapper<Foo>ion没有意义,我需要更复杂的东西,比如Wrapper<Foo>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"可以做类似的事情。在我看来,出于常量正确性的原因,想要一个按值保存常量项的变量似乎是合理的。。。不是因为你不打算更改它。

如果你想变得笨拙,你可以使用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"之外,还有更好的方法来解决这个问题吗?

如果我忽略了这里的一些内容,我深表歉意。但由于你的问题没有提到它,我想知道你是否知道,并考虑过:

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...

如果你想变得笨拙,你可以使用std::pair,而忽略bool:

这清楚地解释了为什么您想要的不能完成,因为此代码不起作用。我使用了const int而不是const Foo,但这是相同的想法。这条线就是它断裂的地方:

theFooBool = std::pair<const Foo, bool> (defaultFoo, false);

复制赋值运算符未声明为const,因为根据定义,复制赋值是更改对象。const是当您希望对象不可更改时使用的。

当然,您可以只使用std::reference_wrapper<const T>,它将为您提供const访问权限,但允许重新绑定。诚然,它不提供价值语义,但这是最接近的。一般来说,大多数人不需要甚至不想要这个,所以它还没有出现。