标签: temporary-objects

在异常情况下将临时对象绑定到非常量引用

我一直读到,在函数调用的情况下,临时变量只能与非常量引用参数绑定。

情况1:-

例如:-

class Simple{
    public: 
       int i;
       Simple(Simple &f)
       {
         i = f.i + 1;
       }
       Simple(int j)
       {
         i = j;
       }
  };

int main()
{
   Simple f1 = Simple(2);   // error no matching call fruit::fruit(fruit)...
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会给我错误,因为我试图用非常量引用参数临时绑定。

案例2:-

try
{
 throw e;
}
catch ( exception& e )
{
}
Run Code Online (Sandbox Code Playgroud)

我已经了解到,当我们抛出异常时,真正传递给 catch 的是抛出的原始异常的副本,即为抛出的对象创建一个临时对象,然后将其传递给 catch 子句。

catch 正在做的是通过非常量引用来捕获这个异常。这与我在案例 1 中展示的相反。

所以,我的问题是:-

1) 是否有允许临时绑定到非常量引用的特定场景。

2)如果有那么在允许这些例外时考虑了哪些因素。

c++ temporary-objects

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

对结构成员的临时绑定引用

我在一些代码库上尝试了 Coverity,我在一个类似于

struct Foo
{
    std::string name;
};

Foo getFoo();
//...
const auto& name = getFoo().name;
useName(name);
Run Code Online (Sandbox Code Playgroud)

这个代码有效吗?

我的直觉是它确实是无效的。但是,在搜索证明时,我遇到了[class.temporary]/6.4,这似乎表明它实际上格式良好。然而,Coverity 发出警告,Coverity 肯定是由一些比我更能解释标准的聪明人写的。

发出的具体 Coverity 警告是

取消引用返回的或超出范围的堆栈指针将在其作用域之后或函数返回之后访问堆栈上的无效位置。

在whateverSurroundingFunction() 中:指向在范围外返回或使用的局部堆栈变量的指针(CWE-562)

在随后的使用name。前面的警告是

out_of_scope:类型的临时变量Foo超出范围

和一种MRE的是这个(荣誉给@ user4581301在评论)。


SO 有一堆关于临时绑定引用的问题,但我所看到的每个问题都有略微不同的上下文,因此这里又出现了另一个问题。

c++ lifetime language-lawyer temporary-objects coverity

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

返回临时 const 引用的行为与本地 const 引用不同?

我试图更好地理解如何将左值和右值作为引用处理,因此我创建了这个玩具示例:

\n
#include <iostream>\n\nstruct Val\n{\n    Val(int num) : num(num){};\n    ~Val()\n    {\n        std::cout << "Destructing with value " << num << std::endl;\n    }\n\n    int num;\n};\n\nconst Val &test(const Val &val)\n{\n    return val;\n}\nint main()\n{\n    std::cout<< "Creating foo with value 5" <<std::endl;\n    const Val &foo = test(Val(5));\n    std::cout<< "Creating bar with value 3" <<std::endl;\n    const Val &bar(3);\n    std::cout<< "Finishing main function" <<std::endl;\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这打印出:

\n
Creating foo with value 5\nDestructing with value 5\nCreating bar with value 3\nFinishing main function\nDestructing with value 3\n …
Run Code Online (Sandbox Code Playgroud)

c++ reference temporary lifetime temporary-objects

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

访问结构中的数组会导致发出叮当声警告

struct test{
   char c_arr[1];
};

test array[1] = {{1}};

test get(int index){
 return array[index];
}

int main(){
  char* a =  get(0).c_arr;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译它g++没有警告但clang++打印以下内容:

warning: temporary whose address is used as value of local variable 'a' will be destroyed at the end of the full-expression
Run Code Online (Sandbox Code Playgroud)

这不正确吗?不get(0).c_arr返回指向全局数组的指针?

还是get(0)返回一个临时变量并且编译器错误地认为c_arr它只是它的一个实例,而不是全局变量?

编辑

为什么将此临时变量传递给函数可以在没有警告的情况下工作?

void call(char* in){}

int main(){
  call(get(0).c_arr);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ temporary-objects

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

为什么在函数内部初始化时 C++ 对象会被破坏?我能做些什么来防止它?

在这里,当我推入堆栈时,为什么对象会被销毁?

#include <iostream>
#include <stack>

class One
{
private:
        int i;
public:
        One(int i) {this->i = i;}
        ~One() {std::cout << "value " << this->i << " is destroyed\n";}
};

int main()
{
        std::stack<One> stack;
        stack.push(One(1));
        stack.push(One(2));

        std::cout << "Now I'll stop\n";
}
Run Code Online (Sandbox Code Playgroud)

我之前预计不会看到任何输出Now I'll stop。但我明白了

value 1 is destroyed
value 2 is destroyed
Now I'll stop
value 1 is destroyed
value 2 is destroyed
Run Code Online (Sandbox Code Playgroud)

如果我想防止它们被破坏,我该怎么办?

c++ temporary-objects

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

临时对象的存储持续时间是多少:自动、线程、静态或动态?

临时对象存储持续时间是多少:自动、线程、静态或动态?

我知道临时对象的生命周期在创建它的完整表达式处或之前结束,除非它绑定到引用,在这种情况下,它的生命周期将扩展到引用的生命周期,这给了我们一个下限临时对象的存储持续时间结束。

c++ temporary-objects storage-duration

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

C++ - 通过引用引用调用的基本实现?

考虑以下代码(最小版本):

#include <iostream>

struct Base
{
    virtual ~Base() {}

    virtual void test() const { std::cout << "base"; }
};

struct Derived : public Base
{
    void test() const { std::cout << "derived"; }
};

struct Composite
{
    const Derived &ref;

    Composite(const Derived &ref) : ref(ref) {}

    void testRef() const { ref.test(); }
};

int main()
{
    Composite c((Derived()));
    c.testRef();
}
Run Code Online (Sandbox Code Playgroud)

当使用最新的MinGW g ++时,这实际上产生了"基础"!这是编译器错误还是我错过了什么?有人可以在VS中测试这个吗?

我认为自己是一位经验丰富的C++程序员,经常使用多态,基于堆栈的引用,临时对象(C++标准12.2)等.因此我知道应该应用终身延长.

只有在Base(虚拟或非虚拟)中定义析构函数并使用临时(即后续用法生成'derived')时,才会出现此行为:

int main()
{
    Derived d;
    Composite c(d);
    c.testRef();
}
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism mingw temporary-objects

2
推荐指数
1
解决办法
135
查看次数

调用vector.push_back()时避免使用copy-constructor /析构函数

MemRef是一个小对象,包含指向内存的指针和长度.它是优化项目的核心,可以最大限度地减少关键部分中的字符串复制.令牌是一个deque<MemRef>.

当我在输入缓冲区中识别标记时,我想构造MemRefs并将它们添加到令牌deque中.首先尝试的是:

MemRef foo(token_begin, token_len);
tokens.push_back( foo );
Run Code Online (Sandbox Code Playgroud)

自从我在这里看到dtor调用以来,它让我觉得foo正在创建,复制,然后被破坏.接下来的尝试是:

tokens.push_back( MemRef(token_begin, token_len) );
Run Code Online (Sandbox Code Playgroud)

但我看到了同样的行为.我的猜测是,正在创建一个临时文件,复制到双端队列中,然后销毁,这也许就是"移动语义"主题的来源(我很不清楚).

实际上,有没有办法MemRef直接构建令牌双端队列,而不创建和销毁临时?

(我正在使用Apple LLVM版本5.0(clang-500.2.79)和--std = c ++ 11)

c++ copy-constructor temporary-objects move-semantics

2
推荐指数
1
解决办法
215
查看次数

如何在构造向量时摆脱(一)不必要的副本?

我有一个class A处理我的资源(非常大).现在我需要一个这样的矢量std::vector<A> vec_of_A (3, A(int N)).问题是vector首先构造临时对象A(int N),然后从中复制构造三次然后销毁该临时对象.由于我A(int N)分配了相当大的内存,我最终(暂时)内存需求比实际需要大33%.

如何在避免不必要的构造函数vectorA同时构建?(我class A满足所有五条规则).

编辑:对不起,我没有意识到默认构造对象的重要性A.我的问题不是默认构造函数,而是参数化构造函数.

c++ vector temporary-objects c++11

2
推荐指数
1
解决办法
70
查看次数

完美的转发和构造函数

我试图理解完美转发和构造函数的相互作用.我的例子如下:

#include <utility>
#include <iostream>


template<typename A, typename B>
using disable_if_same_or_derived =
  std::enable_if_t<
    !std::is_base_of<
      A,
      std::remove_reference_t<B>
    >::value
  >;


template<class T>
class wrapper {
  public:
    // perfect forwarding ctor in order not to copy or move if unnecessary
    template<
      class T0,
      class = disable_if_same_or_derived<wrapper,T0> // do not use this instead of the copy ctor
    > explicit
    wrapper(T0&& x)
      : x(std::forward<T0>(x))
    {}

  private:
    T x;
};


class trace {
  public:
    trace() {}
    trace(const trace&) { std::cout << "copy ctor\n"; }
    trace& operator=(const …
Run Code Online (Sandbox Code Playgroud)

c++ temporary-objects perfect-forwarding

2
推荐指数
1
解决办法
345
查看次数