当前位置: 首页 > 知识库问答 >
问题:

返回本地对象的元组

邵畅
2023-03-14

如何利用结构化绑定和元组来返回函数的本地对象?

在函数中,我创建相互引用的本地对象,我希望以元组的形式返回这些对象,并在调用函数时使用结构化绑定来标识它们。我现在有:

std::tuple<Owner&&, State<Controller>&&, State<Ancillary>&&, State<Compressor>&&>
inline makeOwner() {
    State<Controller>&& controller = State<Controller>();
    State<Ancillary>&&  ancillary  = State<Ancillary>();
    State<Compressor>&& compressor = State<Compressor>();

    Owner&& owner = Owner(controller, ancillary, compressor);

    return {owner, controller, ancillary, compressor};
}

// using the function later

const &&[owner, controller, ancillary, compressor] = makeOwner();

这不起作用,我得到一个错误,说返回值不能转换为前面提到的返回类型的元组。我不确定为什么会这样,因为类型与声明匹配。

最终,我试图创建一个方便的函数,这样我就不必每次想创建一个新的所有者时都在函数中键入四行。这是我使用结构化绑定使其更容易的尝试。

编辑:我应该注意,我希望最后一行中的绑定引用owner中的对象。因此,副本不足。

共有2个答案

夏侯智鑫
2023-03-14
inline auto makeOwner() {
   struct bundle {
     State<Controller> controller;
     State<Ancillary> ancillary;
     State<Compressor> compressor;
     Owner owner = Owner(controller, ancillary, compressor);
     bundle(bundle  const&)=delete;
     bundle& operator=(bundle  const&)=delete;
   };
   return bundle{};
}

// using the function later

const auto&&[owner, controller, ancillary, compressor] = makeOwner();

这里我们使用这样一个事实,即结构,即使是匿名的结构,也可以像元组一样被分解。

活生生的例子。

东郭鸿福
2023-03-14

我希望最后一行的绑定引用所有者内部的对象。

让我们忽略所有新的语言功能,回到基础。你认为这会怎样?

int&& f() { return 0; }
int&& r = f();

你想让r成为f内部局部变量的引用吗?但是在执行f()的最后,它会被破坏。这段代码可以编译,但r是一个悬而未决的参考。

唯一安全的方法是确保f()返回一个对象的引用,该对象肯定比函数更有效。可能是局部的静态的,可能是全局的,可能是类的一个成员变量,f是类的一个成员函数,等等:

int global = 0;
int&& f() { return std::move(global); }
int&& r = f(); // okay, r is a reference to global, no dangling

或者,如果这没有意义,那么需要按值返回一个对象。你仍然可以参考它。或者不是:

int f() { return 0; }
int&& r = f(); // okay, lifetime extension
int i = f();   // okay, prvalue elision

一旦我们添加了tuple和结构化绑定的所有复杂性,相同的基本原则就会适用。通过值返回本地非静态对象,或者通过引用返回其他对象。但是不要通过引用返回本地非静态对象。

最终,我试图创建一个方便的函数,这样我就不必每次想创建一个新的所有者时都在函数中键入四行。这是我使用结构化绑定使其更容易的尝试。

为什么不直接做一个类型呢?

struct X {
    X() : owner(controller, ancillary, compressor) { }
    X(X const&) = delete;
    X& operator=(X const&) = delete;

    State<Controller> controller;
    State<Ancillary>  ancillary;
    State<Compressor> compressor;
    Owner owner;        
};

// lifetime extension on the X, no copies anywhere
// note that owner is last
auto&& [controller, ancillary, compressor, owner] = X();

// no lifetime extension, but also no copies because
// prvalue elision
auto [controller, ancillary, compressor, owner] = X();
 类似资料:
  • 问题内容: 为了获取今天时间对象的本地开始时间,我提取了YMD并重建了新的日期。看起来像是在跳动。我还会错过其他一些标准库功能吗? 代码也可以在http://play.golang.org/p/OSRl0nxyB7上运行: 问题答案: 问题的标题和正文都要求“今天开始是当地的(芝加哥)”。问题中的函数正确地做到了这一点。接受功能的权利要求是更好的解决方案,但它返回一个不同的结果; 它不会在今天开始

  • 假设每种颜色总是有一辆车。所以我总是在找一辆车,不多也不少。 如何确保始终有一个对象被找到并返回?

  • 我有一个场景,我想把从JPA存储库中的本机查询中提取的数据映射到自定义对象。 我的存储库代码如下: 我的自定义类代码如下: 但是我在运行应用程序时遇到了以下错误 原因:org。springframework。数据地图。PropertyReferenceException:找不到类型优惠券的属性FindTodayPoffer! 我应该移动名称查询和sql结果映射到我的实体类吗?问题是我不想污染我的实

  • 我一直在研究猫鼬文档,但我找不到一种方法来实现我想要做的事情。考虑一个MangGDB用户集合。还可以考虑一个包含DB集合中所有字段的蒙古人用户模式。 现在,我想登录到控制台,所有用户,但属性已更改。有点像: 用户。图例(): 给定的异步类型。find()函数我不确定这是否可以实现。我来自C#和PHP背景,只处理关系数据库,这可以通过在用户类中使用只返回所需值的函数轻松实现。 能做到吗?!

  • 我使用mysql存储过程来检索对象列表。这可能吗? 我在看这篇文章 问题: > 如何使用结果集检索select语句中的对象列表? 如何将结果集映射到对象列表? CREATE DEFINER=@PROCEDURE(ININT,OUTINT,OUTINT,OUTVARCHAR(50),OUTVARCHAR(50),OUTFLOAT 内部连接(从rate中选择aid,r.rate,re.country_

  • 当在testng单元testcase中运行时,JAXB将XML文件解组到对象中工作正常。 当相同的代码被用来在另一个进程中解封相同的XML文件时,我得到了一个空对象。我可以验证对象是为XML文档中的每个元素创建的,并且所有适配器都被调用。在unmarshaller中设置事件处理程序,但没有验证问题。当我设置xmlns属性和前缀时,即使返回空对象,行为也略有不同。 我看了好几篇文章,但都无法与我面临