在阅读了关于cppreference的复制省略后,我想玩异常和复制省略.所以我在coliru上用gcc 7.2编写了以下代码
#include <iostream>
class Exception
{
public:
Exception() { std::cout << "constructed\n"; }
Exception(Exception& other) {std::cout << "copy constructed\n";}
Exception(const Exception& other) {std::cout << "copy constructed\n";}
Exception(Exception&& other) {std::cout << "move constructed\n";}
};
void foo()
{
throw Exception();
}
int main()
{
try
{
foo();
}
catch(Exception e )
{
}
}
Run Code Online (Sandbox Code Playgroud)
产量
构造的
复制品
我们可以看到复制构造函数被调用,即使用-O2调用gcc也会发生这种情况.在我看来,此代码应该有资格根据以下条款复制elision:
处理异常时,如果catch子句的参数与抛出的异常对象具有相同的类型(忽略顶级cv限定),则省略该副本,并且catch子句的主体直接访问异常对象,如如果被引用抓住了
那么为什么复制构造函数被调用?为什么复制省略在这种情况下不起作用?
我已经在N4268草案中看到了一个名为"未命名的左值"的概念,下面是罢工部分
[注意:
Temporaries,未命名的左值和没有链接的命名左值是当相应的template-parameter具有引用类型时,临时对象不是可接受的模板参数.[例子:......]]
我搜索了很多,但stackoverflow和谷歌都没有给我一个答案.我只发现了关于价值类别的这篇文章
什么是rvalues,lvalues,xvalues,glvalues和prvalues
但它没有帮助.
假设我有这个代码
template<typename T2, typename T = int>
struct X
{
static double f;
};
template<typename T>
double X<T>::f = 14.0;
Run Code Online (Sandbox Code Playgroud)
如果我尝试编译clang给我以下错误
声明的嵌套名称说明符'X ::'不引用类,类模板或类模板部分特化
对于海湾合作委员会:
错误:非模板'double X :: f'的模板定义
问题是 :
为什么编译器希望我们像这样专门化struct X:
template<typename T2>
struct X<T2,int>
{
static double f;
};
Run Code Online (Sandbox Code Playgroud)
第一个声明int作为默认参数,为什么编译器不选择此声明?
我在标准锚[temp.spec]中搜索但它没有帮助.
我问这个问题后,回答了这个一个对SO.
谢谢你的帮助 !
我试图在main()中捕获char*类型异常,但程序崩溃时出现以下消息:在抛出'char const*'实例后调用terminate这是代码:
#include <iostream>
int main ()
{
char myarray[10];
try
{
for (int n=0; n<=10; n++)
{
if (n>9)
throw "Out of range";
myarray[n]='a';
}
}
catch (char * str)
{
std::cout << "Exception: " << str << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)