Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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/1/ms-access/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++ 如何为构造函数生成的右值赋予左值的生存期?_C++ - Fatal编程技术网

C++ 如何为构造函数生成的右值赋予左值的生存期?

C++ 如何为构造函数生成的右值赋予左值的生存期?,c++,C++,我有一个类型为的RAII对象,它的析构函数在超出范围时撤消它引起的突变,就像std::lock\u guard。问题是用户必须键入auto,否则析构函数将在model.get_info()之前被调用;我不喜欢用户必须键入auto.=。为什么用户会想创建一个从未使用过的对象 我的第一个想法是使构造函数[[nodiscard]];但是构造函数没有返回值。有没有办法告诉编译器操作右值应该有左值生存期?必须这样做。别无选择 NAG Automatic Differention DCO library就是

我有一个类型为
的RAII对象,它的析构函数在超出范围时撤消它引起的突变,就像
std::lock\u guard
。问题是用户必须键入
auto
,否则析构函数将在
model.get_info()
之前被调用;我不喜欢用户必须键入
auto.=
。为什么用户会想创建一个从未使用过的对象


我的第一个想法是使构造函数
[[nodiscard]]
;但是构造函数没有返回值。有没有办法告诉编译器操作右值应该有左值生存期?

必须这样做。别无选择

NAG Automatic Differention DCO library就是一个很好的例子,在这里,您必须向代码中添加大量的
const auto&
,因为它们依赖于销毁顺序来创建图形(RAII,就像您依赖于此一样)


也就是说,即使使用
const auto&
,也可以确保
在需要时不会被更改。

对于
std::lock\u guard
来说,这也是一个未解决的问题,如果您忘记给它命名,就会出现错误

这里有一些技巧:


关于这一点和此处链接的其他陷阱的讨论:

要求用户告诉
操纵
ctor他们想要运行什么代码。因此,将其更改为以可调用为参数并调用它:

while(model.condition) {
    auto data = yield_data();
    auto _= manipulate(model, data);
    model.get_info(args);
}

如果不将右值绑定到某个变量,就无法将右值的生存期延长到其所在的完整表达式之外。因此,不幸的是,您必须以某种方式将右值转换为左值,或者将实际工作转移到一个不超过右值的范围内

实现后者的一种方法是使用回调,如本文其他答案所示

或者,由于保证了复制省略,您可以将
操纵()
转换为函数,而不是直接调用构造函数。这至少允许您利用
[[nodiscard]]
属性,例如:

manipulate(model, data, [&model, &args] {
    model.get_info(args);
});

您可以使用静态代码分析工具来防止此类错误,如clang-tidy。在C++17中删除了
寄存器之后,有人提议将其重新用于延长临时程序的使用寿命。我不知道今天的情况如何,但假设作者继续追求它,也许将来会有更好的方法。谁知道呢。@MatthieuBrucher如果不将右值绑定到某个变量,就无法将右值的生存期延长到其完整表达式之外。我对这个问题的理解是,OP对他甚至不能使用上面介绍的函数方法所允许的
[[nodiscard]]]
表示遗憾。我编辑了答案,让它更清楚…
[[nodiscard]] manipulate begin_transaction(const Model& model, const Data& data)
{
    return { model, data };
}

while(model.condition)
{
    auto data = yield_data();
    auto guard = begin_transaction(model, data);
    model.get_info(args);
}