标签: temporary-objects

为什么非const引用临时对象?

C++只允许将临时对象分配给const引用.它不允许分配临时对象来引用.

例如:

String& a = String("test");         // Error
const String& a = String("test");   // Ok
Run Code Online (Sandbox Code Playgroud)

无论我到哪里谷歌这个结果,我只看到以下答案

  1. 修改临时对象会导致无法识别的问题
  2. 修改临时对象很危险
  3. 在某些时候,你会忘记它是一个临时变量

有人说,临时对象在声明后消失了.所以你不应该修改它.

如果C++,如此热衷于阻止修改临时对象,它应该阻止读取临时对象吗?如果临时对象消失了,那么从那里读取内容是没有意义的吗?权利可能发生的可能情况也可能涉及阅读.

那为什么它一直阻止写入并允许读取?

请给我一个可靠的c ++代码说明.

请不要通过指出一些替代方案来偏离问题.请给我一个可靠的答案代码,为什么const int&被允许,而int&不允许用于临时对象.

一个说&&在那里..我的问题不同..另一个说,改变不会反映..改变也不会反映即使它也是const int&.例如:双倍; Const int&i = a; 一个++; 不会影响我..

c++ temporary-objects

45
推荐指数
3
解决办法
1万
查看次数

为什么const引用不能延长通过函数传递的临时对象的寿命?

在下面的简单示例中,为什么不能ref2绑定到结果min(x,y+1)

#include <cstdio>
template< typename T > const T& min(const T& a, const T& b){ return a < b ? a : b ; }

int main(){
      int x = 10, y = 2;
      const int& ref = min(x,y); //OK
      const int& ref2 = min(x,y+1); //NOT OK, WHY?
      return ref2; // Compiles to return 0
}
Run Code Online (Sandbox Code Playgroud)

现场示例 -产生:

main:
  xor eax, eax
  ret
Run Code Online (Sandbox Code Playgroud)

编辑: 我认为以下示例更好地描述了一种情况。

#include <stdio.h>


template< typename T >
constexpr T const& min( T …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer temporary-objects c++11

45
推荐指数
3
解决办法
2683
查看次数

临时对象 - 何时创建,如何在代码中识别它们?

在Eckel,第1卷,第367页

//: C08:ConstReturnValues.cpp
// Constant return by value
// Result cannot be used as an lvalue
class X {
   int i;
public:
   X(int ii = 0);
   void modify();
};

X::X(int ii) { i = ii; }

void X::modify() { i++; }

X f5() {
   return X();
}

const X f6() {
   return X();
}

void f7(X& x) { // Pass by non-const reference
   x.modify();
}

int main() {
   f5() = X(1); // OK -- non-const return value
   f5().modify(); // OK …
Run Code Online (Sandbox Code Playgroud)

c++ temporary-objects

33
推荐指数
3
解决办法
3万
查看次数

大括号的类型如何影响 C++ 中的对象生命周期?

我的一个朋友给我看了一个 C++20 程序:

#include <iostream>

struct A
{
    A() {std::cout << "A()\n";}
    ~A() {std::cout << "~A()\n";}
};

struct B
{
    const A &a;
};

int main()
{
    B x({});
    std::cout << "---\n";
    B y{{}};
    std::cout << "---\n";
    B z{A{}};
    std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)

在 GCC 中,它打印:

A()
~A()
---
A()
---
A()
---
~A()
~A()
Run Code Online (Sandbox Code Playgroud)

https://gcc.godbolt.org/z/ce3M3dPeo

因此,A在 y 和 z 情况下,的寿命会延长。

在 Visual Studio 中,结果是不同的:

A()
~A()
---
A()
---
A()
~A()
---
~A()
Run Code Online (Sandbox Code Playgroud)

所以A只有在 y …

c++ initialization object-lifetime temporary-objects c++20

33
推荐指数
1
解决办法
1115
查看次数

两个临时表的地址是否保证在同一个表达式中不同?

考虑以下程序:

#include <iostream>

int const * f(int const &i) 
{ 
  return &i; 
}

int main() 
{
  std::cout << f(42);  // #1
  std::cout << f(42);  // #2

  std::cout << f(42) << f(42);  // #3
}
Run Code Online (Sandbox Code Playgroud)

根据编译器和设置的优化级别,打印在行上的地址可能彼此不同#1#2也可能不同。

但是,无论选择何种编译器或优化级别,行#3中打印的 2 个地址总是彼此不同。

这是一个可以玩的演示

那么f在每种情况下返回什么的规则是什么?

c++ pointers language-lawyer temporary-objects

30
推荐指数
2
解决办法
1776
查看次数

非const引用绑定到临时,Visual Studio错误?

我在编译一些可移植代码时碰到了这个gcc.基本上这个奇怪的代码在Visual Studio中编译,这真的让我大吃一惊:

class Zebra {int x;};
Zebra goo() {Zebra z; return z;}
void foo(Zebra &x)
{
    Zebra y;
    x = y;
    foo(goo());
}
Run Code Online (Sandbox Code Playgroud)

Visual studio让这一个飞.gcc将捕获此作为编译错误.有趣的是,如果你输入def Zebra为int,VC++会抱怨.相当矛盾的行为.思考?

c++ visual-studio temporary-objects

23
推荐指数
2
解决办法
2611
查看次数

是否从临时有效的 C++ 代码中获取引用?

我使用了以下语法糖:

for (auto& numberString: {"one", "two", "three", "four"}) { /* ... */}
Run Code Online (Sandbox Code Playgroud)

这是有效的代码吗?AFAIK,基于这个问题,这应该是非法的,但代码按预期运行。我认为我对此事的理解不正确。

据我所知,只有文字不应该有内存地址,但链接的问题正在讨论临时值和右值

c++ reference temporary-objects c++17

23
推荐指数
1
解决办法
1274
查看次数

for循环中pIter!= cont.end()的性能

我最近通过Herb Sutter获得了"Exceptional C++",我对他在第6项 - 临时对象中提出的特别建议表示严重怀疑.

他提供了在以下代码中查找不必要的临时对象:

string FindAddr(list<Employee> emps, string name) 
{
  for (list<Employee>::iterator i = emps.begin(); i != emps.end(); i++)
  {
    if( *i == name )
    {
      return i->addr;
    }
  }
  return "";
}
Run Code Online (Sandbox Code Playgroud)

作为示例之一,他建议预先计算emps.end()循环之前的值,因为每次迭代都会创建一个临时对象:

对于大多数容器(包括列表),调用end()返回一个必须构造和销毁的临时对象.因为值不会改变,所以在每次循环迭代中重新计算(并重建和重新描述)它都是不必要的低效和不美观的.该值应仅计算一次,存储在本地对象中,然后重复使用.

他建议用以下内容代替:

list<Employee>::const_iterator end(emps.end());
for (list<Employee>::const_iterator i = emps.begin(); i != end; ++i)
Run Code Online (Sandbox Code Playgroud)

对我来说,这是不必要的并发症.即使用compact替换丑陋的类型声明auto,他仍然会获得两行代码而不是一行代码.更重要的是,他end在外部范围内有这个变量.

我确信现代编译器无论如何都会优化这段代码,因为我实际上const_iterator在这里使用并且很容易检查循环内容是否以某种方式访问​​容器.编译器在过去的13年里变得更聪明,对吧?

无论如何,i != emps.end()在大多数情况下,我更喜欢第一个版本,我不太担心性能.但我想知道,这是否是一种我可以依靠编译器进行优化的结构?

更新

感谢您就如何更好地制作这些无用的代码提出建议.请注意,我的问题是关于编译器,而不是编程技术.现在唯一相关的答案来自NPEEllioh.

c++ performance stl compiler-optimization temporary-objects

22
推荐指数
2
解决办法
1189
查看次数

在参数列表中构造一个对象并将指向该对象内部数据的指针传递给函数安全吗?

下面的 C++ 代码格式正确吗?std::string函数执行完成之前还是之后会被销毁?

void my_function(const char*);

...

my_function(std::string("Something").c_str());
Run Code Online (Sandbox Code Playgroud)

我知道我可以做到my_function("Something"),但我用std::string这种方式来说明我的观点。

c++ string temporary-objects

21
推荐指数
1
解决办法
822
查看次数

const引用临时值与返回值优化

我知道为一个const左值引用分配一个rvalue会延长临时值的生命周期,直到范围结束.但是,我不清楚何时使用它以及何时依赖返回值优化.

LargeObject lofactory( ... ) {
     // construct a LargeObject in a way that is OK for RVO/NRVO
}

int main() {
    const LargeObject& mylo1 = lofactory( ... ); // using const&
    LargeObject mylo2 = lofactory( ... ); // same as above because of RVO/NRVO ?
}
Run Code Online (Sandbox Code Playgroud)

根据Scot Meyers的"更有效的C++"(第20项),编译器可以优化第二种方法来构建适当的对象(这将是理想的,并且正是人们试图用const&第一种方法实现的).

  1. 是否有任何普遍接受的规则或最佳实践何时使用const&临时工具以及何时依赖RVO/NRVO?
  2. 是否存在使用该const&方法比不使用该方法更糟糕的情况?(我正在考虑关于C++ 11移动语义的例子,如果LargeObject实现了那些......)

c++ optimization const-reference temporary-objects return-value-optimization

20
推荐指数
2
解决办法
6038
查看次数