- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要调用一个函数为我返回一个对象。问题是对象有一个析构函数,它可以在函数输出被分配给另一个对象之前破坏数据。在我的程序中,我有一个 operator+,它将两个矩阵相加并返回两个矩阵的和:
C=A+B
根据名称返回值优化 (NRVO),以下代码不应立即调用析构函数:
Matrix operator+(const Matrix &m1, const Matrix &m2)
{
Matrix sum;
m1.clone(sum);
for...
for...
sum.members[i][j]+=m2.members[i][j];
return sum;
}
我的问题是我对信任 NRVO 没有信心,因为它取决于编译器。如果我把代码给别人,他可能会编译代码,而他的编译器会给出不同的结果。
那么,有什么方法可以强制编译器提供我真正需要的东西,或者我必须将我的代码更改为如下不合需要的形式吗?
Matrix sum(Matrix &result, const Matrix &m1, const Matrix &m2)
编辑:
只是为了解释更多,我假设考虑到 NRVO,程序运行如下:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
sum is returned but its destructor is not called
the value of sum is directed to variable C
after function containing variable C reaches end, the destructor of C is called.
当不应用 NRVO 时,我预计:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
sum is returned and its destructor is called which releases all data allocations
the return value of the operator+ is already destroyed so an invalid data is associated to variable C
...
最佳答案
The problem is that the object has a destructor which can ruin the data before the function output is being assigned into another object.
这不是问题。对象要么被正确复制,要么通过优化消除不必要的复制。如果您的复制 ctor 正确实现,最终结果将是相同的(当然除了不太理想的代码)。如果对象复制非常昂贵,您可能应该使用写入语义上的复制,而实际的 Matrix 对象将是在堆上创建的真实对象的薄包装器。
不应用 NRVO 时实际会发生什么:
compiler reaches to C=A+B
operator + is called
object sum is created
object sum is calculated as sum of m1 and m2
temporary object of type Matrix created as a copy of object sum
object sum destroyed
temporary assigned to C
如您所见,最终结果是相同的,只是效率较低(创建了临时对象)
关于c++ - 我必须依赖编译器 NRVO 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27411388/
我看到了这个问题 When is an object "out of scope"? 我看了sparc_spread 的回答,发现其中有一个问题。在他的回答的这一部分: Circle myFunc (
在程序中如下 #include struct A { A() { std::cout << "0"; } A( const A & ) { std::cout << "1"; }
在以下示例中,根据 this article 应用 NRVO(命名返回值优化): std::string f1() { std::string str; return str; //
#include using namespace std; int gc = 0; struct A { int id; A():id(gc++) { cout 1)。并且符合规范
class Date { private: int day,month,year; public: Date (int d,int m,int y) { day=d; month=m; year=y;
我们有一个广泛使用 out 参数的代码库,因为每个函数都可能因某些错误枚举而失败。这变得非常困惑,代码有时不可读。 我想消除这种模式并引入更现代的方法。 目标是转变: error_t fn(param
当我在 VS2010 中运行此代码时,不应用 NRVO。 #include class A { public: A() { printf( "I am in constructor\
我认为应该这样做,因为它对正确性很重要。但是,我很惊讶地看到 Clang 的输出。考虑以下代码: #include struct S { int i; S(int i) : i(i)
我希望了解 C++ 中 NRVO 的局限性。具有初始命名声明和单个返回的函数是否会针对 NRVO 进行优化并省略 T val,即使函数 myFunc() 具有抛出的可能性? T myFunc(bool
我有以下代码。 #include struct Box { Box() { std::cout << "constructed at " << this << '\n'; }
返回值优化机制的简短(可能过时且过于简单)总结如下 this : an implementation may create a hidden object in the caller's stack
我已经阅读了一些关于 move 函数的帖子(例如 http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c
我需要调用一个函数为我返回一个对象。问题是对象有一个析构函数,它可以在函数输出被分配给另一个对象之前破坏数据。在我的程序中,我有一个 operator+,它将两个矩阵相加并返回两个矩阵的和: C=A+
我刚刚了解了 RVO(返回值优化)和 NRVO(命名返回值优化)。下面是两个例子 //Example of RVO Bar Foo() { return Bar(); } //Example
如果我编写一个在本地实例化对象然后按值返回的工厂方法,打算利用 NRVO(根据此处的一些答案:c++11 Return value optimization or move?),将指向本地对象的指针/
假设我有这样一个函数: using std::vector; vector build_vector(int n) { if (some_condition(n)) return {};
假设我们有以下代码: std::vector f() { std::vector y; ... return y; } std::vector x = ... x = f(); 似乎编译器
想象一下: S f(S a) { return a; } 为什么不允许别名a和返回值槽? S s = f(t); S s = t; // can't generally transform it
我一直在研究 NRVO 及其对不同编译器的支持,并遇到了奇怪的行为,这相当令人困惑。 示例代码: #include using namespace std; class X
自 1992 年以来我一直在使用 C++(并阅读了大量有关该语言的资料),因此我对这门语言有相当多的了解,但远非全部。我的问题是关于 C++11 命名返回值优化——有什么保证会执行?我倾向于发送非常量
我是一名优秀的程序员,十分优秀!