在阅读这篇关于c 17最终特性的总结时,我对结构化绑定(我的重点)一节感到有点惊讶:
结构化绑定
到目前为止,有一个已知的技巧是滥用std::tie,直接将元组或对分配给不同的变量,而不必手动处理结果类型。这是一个黑客攻击,而且变量必须存在,现在你可以在一行中声明变量并初始化它们:
[a, b, c]=getvalue();
如果需要大括号,getvalues将返回一个元组。提案中没有提到std::pair,因此尚不清楚这是否适用于pair,在某些插入方法中,它是由STL返回的。
我假设他们指的是std::tie
int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);
我认为这是一种推荐的做法。
有人能解释一下为什么他们把上面的例子称为黑客吗?
std::tie
本身具有另一个功能。
它旨在创建一个引用变量的元组
创建对其参数或std::ignore实例的左值引用元组。
这对于创建动态元组很有用,而不必复制变量,因为它们是引用。我只是举了一个cppresiveusecase的例子。
bool operator<(const S& rhs) const
{
// compares n to rhs.n,
// then s to rhs.s,
// then d to rhs.d
return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d);
}
这里创建了元组,但它们不复制变量,而是具有引用。
现在因为他们持有参考资料,你可以“破解”它来做这样的事情
int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);
它将返回的元组的值分配给本身包含引用的元组。
这甚至在CPPreference上也只是一个“注释”
std::tie可以用来解包std::pair,因为std::tuple有一个来自pair的转换赋值
在C17中,他们引入了“结构化绑定”来处理同时分配多个变量的场景。因此,无论是故意的还是黑客的,由于c 17,领带的这种用法应该不再必要了。
无论std::tie
是打算这样使用,还是“黑客”可能是个人观点,我想介绍std::tie
的人最清楚这一点。但是考虑到结构化绑定在那个例子中是如何取代std::tie的,他们想出了一个他们认为更好的解决方案。
一个非常明显的区别是d::忽略。看看这个例子
std::tuple<string, string> data {"Lord", "Buddha"};
auto [a, b] = data; //valid
auto [ , b] = data; //not valid as the identifier is strongly required
string y;
std::tie( std::ignore, y ) = data; //voila
我可以这么简单地说:
在一种函数只能返回一个变量的语言中
int a,b,c;
std::tie(a,b,c) = function_returning_multiple_values();
是一个黑客:
auto [a, b, c] = function_returning_multiple_values();
就像在假设的世界中,C只允许函数使用一个参数一样
int p1, p2, p3;
p1 = ...;
p2 = ...;
p3 = ...;
function_taking_multiple_params(std::tie_params(p1, p2, p3));
会是一个黑客:
function_taking_multiple_params(p1, p2, p3)
你已经习惯了C限制,一个函数最多只能返回一个对象,但实际上它只是一个人工语言限制,就像最多接受一个参数的限制是一个人工语言限制一样。
std::tie是一种针对缺少的语言特性的库攻击。它也有一些缺点:
结构化绑定是否就是它们可能的一切?不,但在大多数情况下,它们是我们所需要的一切。
少了什么?
auto [a, std::string b, c] = foo();
其中,a
和c
具有推断的类型,b
是显式的“std::string”
auto [a, [b1, b2], c] = foo();
其中,从foo
返回的第二个对象是一个类似于tuple的对象。
返回站点的语言功能(一起绕过std::tuple
auto foo() -> [int, int]
而不是
auto foo() -> std::tuple<int, int>
命名返回对象
auto foo() -> [int& key, int& value]
... 好那不是很好吗
再加上准备好一个很酷的新名字——通用返回初始化:
auto minmax_element(It begin, It end) -> [It min_it, It max_it];
auto [min = *min_it, max = *max_it] = minmax_element(...);
简短版本: 我希望能够将结构转换为元组。至少是那种类型。在下面的代码中,convertToTuple函数不起作用,因为可变参数不能用于结构化绑定(据我所知)。关键是:自动 基本上,我需要的是一种将自定义结构的类型转换为元组的方法,元组包含结构中的所有类型。例如: 具体问题: 我想创建一个模板函数,它将一个类型或一个类型列表作为模板参数,并生成一个纹理列表,每个纹理包含一个项目。另一个函数可以对纹理
我在写一个函数,需要返回多个变量,其中一个是位集。然后我遇到了一些奇怪的编译错误。 我尝试了不同的编译器,它们都会产生错误,尽管消息不同。 我试着googling了一下,似乎和公共和私有继承有关。但我认为它不应该以任何方式影响这段代码。 简化代码(C 17)如下所示: 如果我移除方括号(即移除结构化绑定并使用普通自动),它就会工作。 错误消息如下: source.cpp:在函数int main()
我在这里找到了最初的*C结构化绑定方案。它提出了一种轻松绑定多个返回值的方法,即: 但现在我看到每个人都指向 现在我学习了“列表是{like,this}编写的”,出现了一种新的列表语法?为什么?这里的花括号有什么问题?
我已经执行了操作员的命令 头文件: cpp文件: 这对像这样的操作很有效 文件 ,但当用作 库特 结果有: 错误:无法将'std::ostream{aka std::basic_ostream}'左值绑定到'std::basic_ostream 编辑:替换为std::ostream
我试图编写一个通用的obj工厂,使用可变模板调用各种类的构造函数。代码如下: 在大多数例子中,变量arg总是这样写“Args” 错误:没有可行的转换从'__bind( 在移除“ 但我不知道为什么?
假设我有一个类型为 是否可以像这样以嵌套的方式访问元素类型(即在Range for循环中使用时)