Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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++ 这是一种克服省略以保留dtor副作用的方法吗?_C++_C++11 - Fatal编程技术网

C++ 这是一种克服省略以保留dtor副作用的方法吗?

C++ 这是一种克服省略以保留dtor副作用的方法吗?,c++,c++11,C++,C++11,我想确保在RVO候选函数中保留析构函数的副作用。我的目标是在进入和退出时快照堆栈,并显示预期的堆栈变量。这段代码似乎适用于C++11,而不使用编译器特定的选项,但我不知道在早期版本中如何做到这一点,而不添加虚假的测试实例来创建多个返回路径。是否有一些技巧,这是否总是适用于c++11 class Test { public: int m_i; Test() { m_i = 0; cout << "def_ctor" << endl; } Test(c

我想确保在RVO候选函数中保留析构函数的副作用。我的目标是在进入和退出时快照堆栈,并显示预期的堆栈变量。这段代码似乎适用于C++11,而不使用编译器特定的选项,但我不知道在早期版本中如何做到这一点,而不添加虚假的测试实例来创建多个返回路径。是否有一些技巧,这是否总是适用于c++11

class Test {
public:
    int m_i;
    Test() { m_i = 0; cout << "def_ctor" << endl; }
    Test(const Test& arg) { this->m_i = arg.m_i; cout << "copy_ctor" << endl;}
    ~Test() { cout << "dtor needed for side effects" << endl; }
};

Test foo() {
    Test ret;
    return std::move(ret);
}

int main()
{
    Test x=foo();
}
类测试{
公众:
国际货币基金组织;

Test(){m_i=0;cout
std::move
不是魔术,它只是一个返回其参数引用的函数,因此在任何版本的C中都应该可以这样做++

template<typename T>
  const T&
  defeat_rvo(const T& t)
  { return t; }

Test foo() {
    Test ret;
    return defeat_rvo(ret);
}
复制省略规则规定,当return语句中的表达式是“非易失性自动对象的名称”时,可以直接在返回值中构造本地对象,这里不是这种情况,因为它是对对象的引用,而不是对象本身的名称。我不太确定这种情况,但强制转换应该起作用:

Test foo() {
    Test ret;
    return static_cast<const Test&>(ret);
}
testfoo(){
测试ret;
返回静态_-cast(ret);
}

这肯定不是对象的名称,也不是对象别名的名称,而是强制转换表达式。

不要返回您不希望忽略的对象;任何此类更改在将来的维护或重构中都将是脆弱的

一般来说,对象在可能发生省略的情况下应该支持省略;这对移动或复制构造的内容以及析构函数的功能设置了语义限制


违反这些语义限制很容易(
template T copy_of(T const&T){return T;}
,然后
return copy_of(whatever);
,或者
static_cast
,或者其他任何内容)。从代码可维护性的角度来看,简单并不意味着安全。

我知道,至少在历史上,向实例添加volatile会强制运行代码/访问内存地址。是的,RVO只允许用于非volatile对象,但使其易失性会产生其他影响,并且意味着复制构造函数需要能够复制易失性对象。您可以使用返回其参数的测试模板方法吗?因此,您可以编写
return-Test.return(ret);
而不是
return-Test.return(ret);
然后在方法“return”中执行状态检查。它将是一个模板,因此它将返回其参数的类型:
T return(T){…}
(目前无法尝试此操作,但我会稍后再尝试,看看是否有效。)将返回值放在括号中难道不起作用吗?即
return(ret);
&乔纳森·韦克利和本杰明·林德利使用VS2015 U2静态强制转换和(ret)elides。我希望引用强制转换能起作用。唉。
return(ret)
不需要禁止复制省略,在实践中通常不需要。挫败\u rvo()与放入单独的ref变量一样有效。不知道为什么静态强制转换不起作用。将静态强制转换更改为
static\u cast(ret)
确实起作用(与move的作用差不多)但它不是可移植的C++,我错了。只是做了一个<代码>静态分析(RET)
在VS2015中不起作用。它必须被传递到函数中,并且返回的函数参数不会被忽略。根据标准,这似乎是迄今为止最好的解决方案。我会看看人们提出了什么想法,然后再检查。我同意这种观点,但有时我需要插入一个函数来检查t上的自动变量他在堆栈退出时进行堆栈,因此我正在寻找一种安全的方法来执行此操作。当然,这些变量在堆栈上的显示方式是由实现定义的,但这是必须遵守的。@doug然后编写一个范围保护类?为什么要将其与返回值关联?范围保护(非常酷的技术)会阻止“ret”吗在调用例程中被实例化,因此不会出现在当前函数堆栈框架中?
Test foo() {
    Test ret;
    return static_cast<const Test&>(ret);
}