Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.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++ 如何使用结构化绑定复制具有类型为T&;的元素的类似元组的对象;?_C++_C++17_Structured Bindings - Fatal编程技术网

C++ 如何使用结构化绑定复制具有类型为T&;的元素的类似元组的对象;?

C++ 如何使用结构化绑定复制具有类型为T&;的元素的类似元组的对象;?,c++,c++17,structured-bindings,C++,C++17,Structured Bindings,这个问题的根源是我正在设计一个由std::vector实现的二维容器。operator[]的结果类型是一个具有固定数量元素的代理类,然后我想对这个代理类使用结构化绑定,就像std::array一样。这是一个简单的例子: 模板 结构引用{ 集装箱2D*集装箱; 尺寸指数; 模板 decltype(自动)get(){ 返回容器->数据()[I+索引*stride]; } }; /*对象表示容器中的'stride'元素,从'index*stride'开始*/ 模板 结构容器2D{ std::vecto

这个问题的根源是我正在设计一个由
std::vector
实现的二维容器。
operator[]
的结果类型是一个具有固定数量元素的代理类,然后我想对这个代理类使用结构化绑定,就像
std::array
一样。这是一个简单的例子:

模板
结构引用{
集装箱2D*集装箱;
尺寸指数;
模板
decltype(自动)get(){
返回容器->数据()[I+索引*stride];
}
};
/*对象表示容器中的'stride'元素,从'index*stride'开始*/
模板
结构容器2D{
std::vector&data();
/*通过std::vector实现,简化模板参数T*/
参考运算符[](大小索引);
/*运算符[]只是构造一个引用对象*/
/*所以它返回一个右值*/
};
名称空间标准{
模板
结构元组大小{
静态constexpr size\u t值=步幅;
};
模板
结构元组元素{
/*2种选择:*/
/*第一:元组元素t=t*/
typedef int类型;
};
}
在这种情况下,我尝试:

Container2D容器;
/*初始化*/
自动[a,b]=容器[0];
/*获取每个元素的副本*/
自动&[c,d]=容器[0];
/*编译错误*/
但是编译器说,“对'reference'类型的非常量左值引用不能绑定到'reference'类型的临时引用”

因此,如果我想通过结构化绑定修改元素,我必须:

模板
结构元组元素{
/*2种选择:*/
/*第二:元组元素t=t&*/
typedef int&type;
};
然后:

Container2D容器;
/*初始化*/
自动[a,b]=容器[0];
/*获取对每个元素的引用*/
//自动&[c,d]=容器[0];
/*仍然存在编译错误,但谁在乎呢*/
但是在这种情况下,如果我想得到一个副本,我必须声明一些变量来复制这些引用变量<这完全不是我想要的。是否有更好的方法可以轻松正确地处理这两种情况?

除此之外,还有以下问题:

我知道结构化绑定的实现是:

"auto" [const] [volatile] [&/&&] "[" <vars> "]" "=" <expression>
“自动”[const][volatile][&/&&&][“”]=”
并且可以实现为(在类似元组的情况下,简化一些边缘情况):

auto[const][volatile][&/&&]e=;
std::tuple_element_t var_0(get(std::forward(e));
std::tuple_元素_t var_1(get(std::forward(e));
...
语法意味着你可以用一些变量名替换
[a,b,c,…]
,比如
e
,然后
a
b
c
的类型遵循一个奇怪的演绎规则


但是,这个匿名变量始终不是我们想要的,而是
a
b
c
将是我们想要的。那么为什么不确定
a
b
c
的类型呢?它只能将CV限定符和REF操作符应用到<代码> STD: T/ECOD> <代码> A>代码> B<代码>和<代码> C>代码>,使用<代码> Auto&E>代码>和<代码> STD::(e)< /C>表达式,其他处理为以前。

< P>这是一个非常旧的C++新装:
std::vector<bool> x;
auto& rx = x[0]; // does not compile
为了实现这一点,
operator[]
返回一个代理,
get()
将为其返回副本,对其调用
.ref()
将返回一个代理,
get()
将为其返回引用

这个问题本身就相当有趣。在这个语言特性中有一些有趣的紧张关系。我不是委员会成员,但我可以说出一些倾向于这个方向的动机:(1)一致性(2)不同的演绎语义,(3)效率,(4)可教性,(5)生活

请注意,问题中的添加掩盖了一个重要区别。绑定的名称不是引用,而是别名。它们是所指事物的新名称。这是一个重要的区别,因为位字段使用结构化绑定,但无法形成对它们的引用

通过(1),我的意思是,如果元组类绑定是引用,那么它们现在在类的情况下不同于结构化绑定(除非我们以不同的方式这样做,并且损害了位字段的特性)。我们现在在结构化绑定的工作方式上有一个非常微妙的不一致性

所谓(2),我的意思是,在语言的任何地方,
auto&&
都有一种类型的演绎发生。如果将
auto&&[…]
转换为绑定名称为
auto&
的版本,则存在N个不同的演绎,具有潜在的不同左值/右值。这使得他们比现在更加复杂(这相当复杂)

通过(3),我的意思是,如果我们写
auto[…]=…
,我们期望一个拷贝,但不是N个拷贝。在提供的示例中,差别不大,因为复制聚合与复制每个成员相同,但这不是一个固有属性。成员可以使用聚合来共享一些公共状态,否则他们需要拥有自己的副本。拥有多个拷贝操作可能会令人惊讶


通过(4),我的意思是,一开始你可以教某人结构化绑定,你可以说“它们的工作原理就像你用一个对象名替换
[…]
,而绑定名是该部分的新名称。”

问题在于你的
get()
<代码>自动返回类型衰减,返回元素的副本。尝试使用
decltype(auto)get(…)
Edit:将
get
operator[]
混淆清楚:现在,在编写容器[0]时,您无法使用结构化绑定或
auto [a, b] = container[0]; // copy
auto [a, b] = container[0].ref(); // reference-like