【问题标题】:How can I return a grpc::ClientContext from a function?如何从函数返回 grpc::ClientContext?
【发布时间】:2018-09-22 10:54:25
【问题描述】:

我试图通过创建 ClientContexts 的函数来避免重复代码。以下代码编译:

template<typename T>
grpc::ClientContext&& context_with_deadline(T duration) {
    grpc::ClientContext context;
    auto deadline = std::chrono::system_clock::now() + duration;
    context.set_deadline(deadline);
    return std::move(context);
}

如果不将返回类型设置为右值引用,或者没有显式的 std::move (我使用的是 C++ 11,所以我相信 RVO 和复制省略不能保证),它不会编译。

在其他范围内,我现在正在尝试执行此操作,但无法编译:

grpc::ClientContext stream_context = context_with_deadline(std::chrono::milliseconds(3000));

它尝试创建一个临时对象并将其复制到stream_context,由于ClientContext的复制构造函数是私有的(未删除),因此无法完成。

有什么方法可以在不使用unique_ptr 的情况下做到这一点?如果不是,这可以被认为是一个错误吗? (看来应该删除复制构造函数,而不是私有的)。

注意:当我说“不编译”时,意味着编译器发出了以下内容:

错误:“grpc::ClientContext::ClientContext(const grpc::ClientContext&)”在此上下文中是私有的

【问题讨论】:

  • 你能详细说明“不编译”吗?
  • @bipll 完成,谢谢
  • 好的,但是如果它是可移动的,你能声明函数返回grpc::ClientContext,但以return std::move(context);结束吗?命名 RVO 不是必需的,因此您需要给编译器一个提示。
  • @bipll 将函数返回类型声明为 ClientContext 而不是 ClientContext&amp;&amp; 表示该函数无法编译。我猜 RVO 仍然不是必需的,即使有 std::move 提示。
  • 究竟是怎么编译不出来的?好的,那么return ClientContext(std::move(context));

标签: c++ move-semantics grpc


【解决方案1】:

复制构造函数是私有的,并且不存在用户定义的移动构造函数,因此您尝试做的事情是不可能的。与其从方法返回一个新实例,不如让它引用一个实例:

template<typename T>
void context_with_deadline(grpc::ClientContext& context, T duration) {
    auto deadline = std::chrono::system_clock::now() + duration;
    context.set_deadline(deadline);
}

然后这样称呼它:

grpc::ClientContext stream_context;
context_with_deadline(stream_context, std::chrono::milliseconds(3000));

【讨论】:

  • 我正在尝试使用移动构造函数,而不是复制构造函数。为什么做一个移动需要一个公共的拷贝构造函数?
  • 如果我理解正确,= 在某些情况下会触发移动分配(复制省略)。问题是如何将函数返回值移动到局部变量中,如果不可能,是否可以将其视为ClientContext 中的错误。我也尝试调用像ClientContext context(rvalue_reference) 这样的移动构造函数,但这也不起作用 - 它仍然想解析对私有复制构造函数的函数调用。
  • 我已经更新了我的答案。没有移动构造函数。 std::move 只是一个演员表。
  • 编译器不应该生成移动构造函数吗?而且,这是否构成班级中的错误?无法从函数中返回它似乎非常受限。
  • 不,当存在用户定义的复制构造函数时,编译器不会生成移动构造函数,这里就是这种情况。
【解决方案2】:

这是不可能的。在完成以下操作之前,可以使用 std::unique_ptr 解决此问题:

https://github.com/grpc/grpc/issues/16680

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多