我无法理解为什么当周围有完美的转发构造函数时绑定(bind)到const引用参数的临时对象的生命周期会缩短。首先,我们了解绑定(bind)到引用参数的临时变量:它们持续到完整表达式:Atemporaryboundtoareferenceparameterinafunctioncall(5.2.2)persistsuntilthecompletionofthefullexpressioncontainingthecall但是我发现有些情况并非如此(或者我可能只是误解了完整表达式的含义)。让我们举一个简单的例子,首先我们定义一个对象,它有冗长的构造函数和析构函数:structA{A(int
假设我有一个跨平台的Path类:classPath{public://...Pathparent()const;//e.g.,/foo/bar->/foostd::stringconst&as_utf8()const{returnpath;}private:std::stringpath;};parent()成员函数返回this路径的父路径,因此它(正确地)返回一个新构造的Path对象代表它。对于将操作系统级别的路径表示为UTF-8字符串的平台(例如,Unix),as_utf8()直接返回对内部表示的引用似乎是合理的path因为它已经是UTF-8。如果我有这样的代码:std::stri
我应该在这个问题的开头说我认为答案可能是否定的,但我想看看其他人对这个问题的看法。我大部分时间都在编写与Win32API交互的C++,就像大多数C风格的API一样:获取我提供的缓冲区并对其进行操作。或者返回指向我稍后需要释放的缓冲区的指针。这两种情况本质上意味着,如果您想在代码中使用std::string,您必须接受这样一个事实,即您将进行大量的字符串复制每次从临时缓冲区构造std::string时。最好是:能够允许C风格的API安全地直接改变std::string并预先保留其分配并提前设置其大小(以缓解场景1)能够将std::string包裹在现有的char[]中(以缓解场景2)有没
我有一个“记住”对某个对象(例如整数变量)的引用的类。我不能让它引用一个立即销毁的值,我正在寻找一种方法来保护我的类(class)的用户免于意外这样做。右值引用重载是防止传入临时值的好方法吗?structHasRef{int&a;HasRef(int&a):a(a){}voidfoo(){a=1;}};intmain(){intx=5;HasRefr1(x);r1.foo();//workslikeintended.HasRefr2(x+4);r2.foo();//dereferencesthetemporarycreatedbyx+4}私有(private)右值重载可以吗?struc
我试图了解C++17标准保证的生命周期,特别是保证复制省略。让我们从一个例子开始std::stringmake_tmp();std::stringfoo(){returnstd::string{make_tmp().c_str()};}我对正在发生的事情的理解:make_tmp创建一个临时的string我们将调用t;foo返回一个(不必要创建的)临时(t的c_str的拷贝)。标准(甚至是C++17之前的版本)保证t的生命周期是计算完整返回表达式之前的时间。因此,创建t的临时拷贝(将被返回)是安全的。现在copyelisions开始;更具体地说,第一个C++17block中的第二个项目符
在thisquestion用户HappyMittal引用C++03标准第12.2.5节:在构造函数的ctor-initializer(12.6.2)中临时绑定(bind)到引用成员,直到构造函数退出。无论如何,这有什么用?我的意思是,一旦构造函数退出,临时对象就会被销毁,但引用仍然绑定(bind)-现在绑定(bind)到一个已经被销毁的对象。如果外部对象的整个生命周期仍然存在悬空引用,那么如此仔细地指定临时生命周期有什么意义呢?这种行为在什么情况下有用? 最佳答案 将引用成员绑定(bind)到死对象没有用,但明确绑定(bind)到引
这个程序是错误的:structX{inti;};intmain(){(X{}).i=1;}i,临时X{}的子对象,不能用作左值,因为X{}是右值.但是,这会使用GCC5.2.1和-Wall进行静默编译:usingY=int[10];intmain(){(Y{})[0]=1;}如果编译器是正确的,那么这一次,(Y{})的第零个元素,它是(Y{})的子对象,可以是被视为左值。我的问题是:第二个程序格式错误吗?为什么(不是),尽管这两个程序似乎都将临时对象的子对象视为左值? 最佳答案 如果我正在阅读defectreport1213,我相信
boost::optional支持像这样的in_place构造:#include#includeclassFoo{inta,b;public:Foo(intone,inttwo):a(one),b(two){}};intmain(){boost::optionalfooOpt(boost::in_place(1,3));}一旦我们有了一个初始化的fooOpt,有没有办法在不创建临时对象的情况下为它分配一个新的Foo?类似的东西:fooOpt=boost::in_place(1,3);谢谢! 最佳答案 boost::可选#includ
最近我遇到了一个问题,它以某种方式(但仅以某种方式)对我有意义。它基于将临时构造解释为单个(!)构造函数参数的声明。请查看下面的最小示例。#includeclassFoo0{public:Foo0(inta){};voiddoStuff(){std::cout我已经读过这样的表达:Foo(a);被解释(如果有标准构造函数)作为a的声明。这是有道理的,而且完全没问题,因为您可以只使用{}括号使构造显式化。但我不明白的是:为什么bar0的构建有问题?所有Foo都没有标准的构造函数。因此,将Foo0(x)之类的内容解释为x的声明是没有意义的。为什么bar1和bar2的构造有效?对我来说很明显
我有一个情况,我有一个成员返回一个const&,然后这个结果在一个具有相同返回类型的lambda中转发。MSVC2017将这种情况识别为有风险,并发出警告:returningaddressoflocalvariableortemporary。使用clang和其他编译器进行的实证测试表明这是全面的。我不明白的是,为什么这与几个返回相同类型的方法调用不同。例如,这非常有效:classA{public:conststd::string&name()const{returnm_name;}private:std::stringm_name;};classB{public:conststd::s