Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::variant中禁止引用?_C++_Boost_C++17_Variant - Fatal编程技术网

C++ 为什么std::variant中禁止引用?

C++ 为什么std::variant中禁止引用?,c++,boost,c++17,variant,C++,Boost,C++17,Variant,我经常使用boost::variant,对它非常熟悉boost::variant不以任何方式限制有界类型,特别是它们可能是引用: #include <boost/variant.hpp> #include <cassert> int main() { int x = 3; boost::variant<int&, char&> v(x); // v can hold references boost::get<int>(

我经常使用
boost::variant
,对它非常熟悉
boost::variant
不以任何方式限制有界类型,特别是它们可能是引用:

#include <boost/variant.hpp>
#include <cassert>
int main() {
  int x = 3;
  boost::variant<int&, char&> v(x); // v can hold references
  boost::get<int>(v) = 4; // manipulate x through v
  assert(x == 4);
}

基本上,
optional
variant
不允许引用类型的原因是,对于这种情况下的赋值(以及在较小程度上的比较)应该做什么,存在分歧<代码>可选比
变体
更容易在示例中显示,因此我将坚持这一点:

int i = 4, j = 5;
std::optional<int&> o = i;
o = j; // (*)
文件提供了这一基本原理:

重新初始化初始化可选引用的重新绑定语义被选择为在初始化状态之间提供<强>一致性,甚至以与裸C++引用的语义缺乏一致性为代价。确实,

optional
努力在初始化时尽可能地表现出U的行为;但是在
U
T&
的情况下,这样做会导致w.r.T与左值初始化状态不一致

想象>代码>可选< /COD>转发给引用对象的分配(从而改变引用的对象值但不重新绑定),并考虑以下代码:

optional<int&> a = get();
int x = 1 ;
int& rx = x ;
optional<int&> b(rx);
a = b ;


在这一行应该做什么方面缺乏一致意见意味着完全不允许引用更容易,因此,
optional
variant
的大部分值至少可以用于C++17并开始有用。引用总是可以在以后添加的——或者说是这样

一个cast或
std::get(v).get()
,公平地说。你可以使用指针,尽管没有与
可选的相同问题:你是通过引用赋值还是重新放置引用?@Galik在我的应用程序中,我可以使用指针,但我必须编写大量额外的代码。我有很多
boost::get
调用,如果变量包含完整类型或引用,这些调用可以无缝工作。它不能与指针无缝地工作。对不起,应该说
boost::get
boost::apply\u visitor
调用。我可以简单地包装第一个以无缝地处理指针,但包装第二个并不容易。解释是有道理的,谢谢。不过,作为一个天真的用户,我希望我的变体的行为与它当前持有的类型完全相同。我不能重新绑定引用,所以我不希望variant在赋值时重新绑定。“重新绑定是一个更合理的实现,是您真正想要的”我猜您的意思是“您”,而不是我个人,因为我不希望它重新绑定。@olq\u plo我同意天真的期望是
optional
确实通过赋值。但对于那种类型来说,这是一个糟糕的选择。请注意,
boost::optional
。尽管对于variant来说,这是一个合理的选择,所以我可能不应该强迫optional和variant行为相似。@olq\u plo我不同意(a)这是variant的合理选择,(b)optional和variant有意义的不同。如果
optional
variant
具有不同的语义,那将非常混乱
// rebind
o.emplace(j);

// assign through
if (o) {
    *o = j;
} else {
    o.emplace(j);
}
optional<int&> a = get();
int x = 1 ;
int& rx = x ;
optional<int&> b(rx);
a = b ;
assert(!!opt);
*opt=value;