c++ - 结构化绑定(bind)中缺少类型信息

标签 c++ c++17 structured-bindings

我刚刚了解了 C++ 中的结构化绑定(bind),但有一点我不喜欢

auto [x, y] = some_func();

auto吗隐藏了 x 的类型和 y .我得查一下some_func的声明以了解 x 的类型和 y .或者,我可以写

T1 x;
T2 y;
std::tie(x, y) = some_func();

但这只适用于 xy是默认可构造的,而不是 const .有没有办法写

const auto [x, y] = some_func();

对于 x 的非默认构造类型和 y以某种方式使 x 的类型和 y可见的?当我声明 x 时,编译器最好会提示和 y作为与 some_func 不兼容的东西的返回类型,即不是 const auto /* T1, T2 */ [x, y] = some_func(); .


澄清。由于我的问题下面的评论似乎围绕着是否使用 & 展开,之前的一些回答将我的问题误解为“使用哪种语法来提取返回对的数据类型”,我想我需要澄清一下我的问题。

假设我们的代码分布在多个文件中

//
// API.cpp
//
#include <utility>

class Foo {
public:
    Foo () {}
};

Foo foo;


class Bar {
private:
    Bar () {}
public:
    static Bar create () { return Bar(); }
};

Bar bar = Bar::create();


std::pair<int, bool> get_values () {
    return std::make_pair(73, true);
}

std::pair<Foo&, Bar&> get_objects () {
    return std::pair<Foo&, Bar&>(foo, bar);
}

//
// Program.cpp
//
int main (int, char**) {
    const auto [x, y] = get_values();
    const auto& [foo, bar] = get_objects();

    /* Do stuff with x, y, foo and bar */

    return 0;
}

在编写此代码时声明 get_valuesget_objects我内存犹新,所以我知道它们的返回类型。但是在查看 Program.cpp 时一周后,我几乎不记得 main 中的代码了。更不用说其变量的数据类型或 get_values 的返回类型了和 get_objects , 所以我需要打开 API.cpp并找到 get_valuesget_objects了解它们的返回类型。

我的问题是是否有写变量数据类型的语法x , y , foobarmain进入结构化绑定(bind)?最好以一种允许编译器纠正我的方式,如果我犯了错误,那么没有评论。类似的东西

int main (int, char**) {
    // Pseudo-Code
    [const int x, const bool y] = get_values();
    [const Foo& foo, const Bar& bar] = get_objects();
    /* Do stuff with x, y, foo and bar */
    return 0;
}

最佳答案

没有机制可以在结构化绑定(bind)声明中声明“变量”的类型。如果您希望类型名称可见,则必须放弃结构化绑定(bind)声明的便利性。

这很重要,因为结构化绑定(bind)的工作原理。 xy本身并不是真正的变量。它们是访问结构化绑定(bind)语句存储的对象组件的替代方法。它们是声明捕获的对象的组件。只有一个实际变量:未命名变量 auto -推导。您声明的名称只是该对象的组成部分。

理解了这一点,现在考虑这个声明:int i = expr;此代码只要 expr 就有效是可以转换int 的东西.

如果您可以将类型名称放在结构化绑定(bind)声明中,人们就会有相同的期望。他们会期望如果函数返回 tuple<float, int> ,他们可以在 auto [int x, int y] 中捕捉到这一点.但是它们不能,因为被存储的对象是一个tuple<float, int>。 , 它的第一个成员是 float .编译器必须发明一些包含两个 int 的新对象。 s 并进行转换。

但这很危险,尤其是在处理包含引用的返回值时。理论上你可以转tuple<float&, int>进入 tuple<int, int> .但它不会有相同的含义,因为您不能修改被引用的对象。

但同样,用户期望变量声明能够进行此类转换。用户一直依赖它。剥夺这种权力只会在功能中造成困惑。

因此该功能无法做到这一点。

关于c++ - 结构化绑定(bind)中缺少类型信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70236472/

相关文章:

c# - 使用 C++/CLI 将图片插入 Excel 并收到 100x 警告 C4691

c++ - VisualStudio2008 上的 std::vector 似乎没有得到最佳实现 - 太多的复制构造函数调用

c++ - Sizeof 舍入对齐,但编译器仍将对象放置在剩余字节中

c++ - 如果每个参数都可转换为特定类型,则启用构造函数

c++ - 迭代 std::pair<string, some_struct >* 的 vector 时使用结构绑定(bind)

c++ - 两个枚举有一些共同的元素,为什么会产生错误?

c++ - 如何手动使另一个控件发出信号?

c++ - 为什么我不能更改新创建文件的 'last write time'?

c++ - 结构化绑定(bind),引用?是否可以删除它们

c++ - 结构化绑定(bind)和基于范围的;在 gcc 中抑制未使用的警告