C++ 关于将临时绑定到构造函数中的引用成员的虚假警告

C++ 关于将临时绑定到构造函数中的引用成员的虚假警告,c++,c++11,g++,object-lifetime,C++,C++11,G++,Object Lifetime,我理解,如果临时对象绑定到构造函数的初始值设定项列表中的引用成员,那么当构造函数返回时,该对象将被销毁 但是>,请考虑下面的代码: #包括 #包括 使用callback_func=std::function; int func(常量回调函数_func&callback) { 结构包装器 { 常量回调函数&w_cb; 包装器(const callback_func&cb):w_cb{cb}{} int call(){返回this->w_cb()+this->w_cb();} }; 包装wrp{c

我理解,如果临时对象绑定到构造函数的初始值设定项列表中的引用成员,那么当构造函数返回时,该对象将被销毁

<强>但是>,请考虑下面的代码:

#包括
#包括
使用callback_func=std::function;
int
func(常量回调函数_func&callback)
{
结构包装器
{
常量回调函数&w_cb;
包装器(const callback_func&cb):w_cb{cb}{}
int call(){返回this->w_cb()+this->w_cb();}
};
包装wrp{callback};
返回wrp.call();
}
int
main()
{

std::cout这是gcc 4.8中的一个错误,已在4.9中修复。以下是错误报告:


正如Howard Hinnant所指出的,R Sahu的评论已经指出,这是GCC 4.8处理初始值设定项列表的方式中的一个缺陷(这是当时被打破的标准所要求的;感谢Tony D指出的)

将原始示例中的构造函数从

wrapper(const callback_func&cb):w_cb{cb}{

wrapper(const callback_func&cb):w_cb(cb){}
使GCC 4.8.3中的警告消失,创建的可执行文件Valgrind干净。两个程序集文件的差异很大,因此我不在这里发布。GCC 4.9.0为两个版本创建相同的程序集代码


接下来,我用一个用户定义的结构替换了
std::function
,并删除了复制和移动构造函数和赋值运算符。实际上,在GCC 4.8.3中,这保留了警告,但现在也给出了一个警告(稍微有用一点)错误,上面的代码行调用结构的已删除副本构造函数。正如预期的那样,与GCC 4.9.0没有区别。

关闭优化会给我一个seg错误。Valgrind指出问题出在
func(std::function const&)::wrapper::call()
。使用
w\u cb{cb}
对我来说会导致分段冲突。使用
w_cb(cb)
不会遇到同样的问题。在g++4.8.3中测试。我可以用GCC 4.8.2重现Valgrind错误。(不是segfault,很难,程序输出42,并按预期成功退出。)GCC4.9.0生成的可执行文件是Valgrind clean。这些观察结果不会随着不同的优化级别而改变。我震惊地听说它在某些系统上失败了。FWIW在ideone的默认设置(GCC4.8.1,带有
{cb}
)下工作正常。事实上,这个错误不是警告,而是警告是关于什么的,这将是有用的。我必须转到链接以确定…即,一个临时文件实际上是在gcc 4.8中创建的,并且它不会持续足够长的时间。优化可能会导致临时文件不存在?是的,这解释了发生的情况。谢谢对于链接。我做了一些进一步的研究,并将其作为一个答案发布,但我接受你的答案。这是标准中的一个缺陷,GCC正在实施标准的精确措辞,这需要在那里创建一个临时版本。1288博士修复了标准。