Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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++,假设我有: f(T& t){ ... } 有时我想从函数调用中为其提供参数 T GetT() { ... } 像这样: f(GetT()) 即使我确信t的生存期保证持续到表达式结束,它也不会编译,我也不能将t&更改为const t&,因为我需要修改f中的对象 我曾考虑过使用T&,但当我碰巧有T的左值时,我需要move()它,这会让它很尴尬,因为有时我需要在调用f后使用T。在我的例子中,T是普通的旧数据,所以我想它可以工作,但是移动一个对象并在以后使用它感觉不太对 是否有

假设我有:

f(T& t){ ... }  
有时我想从函数调用中为其提供参数

T GetT() { ... }  
像这样:

f(GetT())  
即使我确信
t
的生存期保证持续到表达式结束,它也不会编译,我也不能将
t&
更改为
const t&
,因为我需要修改
f
中的对象
我曾考虑过使用
T&
,但当我碰巧有
T
的左值时,我需要
move()
它,这会让它很尴尬,因为有时我需要在调用
f
后使用
T
。在我的例子中,
T
是普通的旧数据,所以我想它可以工作,但是移动一个对象并在以后使用它感觉不太对

是否有一种优雅的方式允许函数将rval和lval引用都带到可变对象

我只是在做

T t = GetT();  
f(t);

我觉得这至少是一行无用的代码和一份无用的
T

你不能把一个引用绑定到一个临时引用:只有const引用才能做到这一点


我建议您查看此链接

您不能将引用绑定到临时引用:只有const引用可以这样做


我建议您以当前的方式查看此链接,即将对象存储在变量中,这是延长返回对象生存期并允许非常量引用绑定到该对象的正确方法。如果实现了
GetT
,使(N)RVO成为可能,那么就不需要进行无用的复制,因为它是可能的。

您当前所做的方法,即将对象存储在变量中,是延长返回对象的生存期并允许非常量引用绑定到它的正确方法。如果实现了GetT,因此(N)RVO是可能的,那么就不需要进行无用的复制,因为它是可能的。

使用如何

不确定你是否认为它是优雅的,但它看起来是这样的:

struct MyStruct
{
    int i;
};

template<class T>
void foo(T&& t)
{
    static_assert(std::is_base_of<MyStruct, 
                  typename std::remove_reference<T>::type>::value, "ERROR");
    t.i = 1024;
}

MyStruct GetMyStruct()
{
    return MyStruct();
}

int main() 
{
    foo(GetMyStruct());

    MyStruct ms;
    foo(ms);

    return 0;
}
struct MyStruct
{
int i;
};
模板
无效foo(T&T)
{
static_assert(std::is_base_of::value,“ERROR”);
t、 i=1024;
}
MyStruct GetMyStruct()
{
返回MyStruct();
}
int main()
{
foo(GetMyStruct());
MyStruct ms;
foo(ms);
返回0;
}
如何使用

不确定你是否认为它是优雅的,但它看起来是这样的:

struct MyStruct
{
    int i;
};

template<class T>
void foo(T&& t)
{
    static_assert(std::is_base_of<MyStruct, 
                  typename std::remove_reference<T>::type>::value, "ERROR");
    t.i = 1024;
}

MyStruct GetMyStruct()
{
    return MyStruct();
}

int main() 
{
    foo(GetMyStruct());

    MyStruct ms;
    foo(ms);

    return 0;
}
struct MyStruct
{
int i;
};
模板
无效foo(T&T)
{
static_assert(std::is_base_of::value,“ERROR”);
t、 i=1024;
}
MyStruct GetMyStruct()
{
返回MyStruct();
}
int main()
{
foo(GetMyStruct());
MyStruct ms;
foo(ms);
返回0;
}

我想出了一个简单重载问题的解决方案:

f(T&T){…}
f(T&&T){f(T);}


但是仍然有更好的方法。

我想出了一个解决简单过载问题的方法:

f(T&T){…}
f(T&&T){f(T);}


但是仍然有更好的方法。

f(T&T){…}
更改为
f(T){…}
您无法将右值绑定到非常量左值引用的原因是阻止您修改即将超出范围的对象。@richardcriten,这将产生冗余副本。另外,我无法观察到f在T上所做的更改。为什么需要修改
f
中的对象?无法访问修改过的对象,那么修改它的目的是什么呢?@DavidSchwartz有时我用左值调用函数,然后我就能看到变化。这实际上是由调用方自行决定他是否对T的更改感兴趣。将
f(T&T){…}
更改为
f(T){…}
无法将右值绑定到非常量左值引用的原因是为了阻止您修改即将超出范围的对象。@RichardCritten,这将产生冗余副本。另外,我无法观察到f在T上所做的更改。为什么需要修改
f
中的对象?无法访问修改过的对象,那么修改它的目的是什么呢?@DavidSchwartz有时我用左值调用函数,然后我就能看到变化。打电话的人可以自行决定是否对T的改动感兴趣。我知道这一点。不知怎的,你错过了这个问题,我知道。不知怎的,你错过了这个问题。正确的术语现在是“转发参考文献”。正确的术语现在是“转发参考文献”。