C++ 编译器为类生成了noexcept构造函数,该类的成员构造时没有此类保证
举个例子:C++ 编译器为类生成了noexcept构造函数,该类的成员构造时没有此类保证,c++,exception,c++14,C++,Exception,C++14,举个例子: class ClassThatMayThrowInCtor { ClassThatMayThrowInCtor() { if (g_unlucky) throw "Exception"; } }; class Aggregate { ClassThatMayThrowInCtor m_member; }; 就我所知有限,在C++14的某些情况下,编译器可能会生成一个默认的ctor,即noexcept 在这种情况下,它会不
class ClassThatMayThrowInCtor
{
ClassThatMayThrowInCtor()
{
if (g_unlucky) throw "Exception";
}
};
class Aggregate
{
ClassThatMayThrowInCtor m_member;
};
就我所知有限,在C++14的某些情况下,编译器可能会生成一个默认的ctor,即noexcept
在这种情况下,它会不会理解,既然成员的违约CTR不提供任何此类担保,它也不应该提供担保
要求参考上述索赔(在某些情况下…),我未能发现其符合标准,但确实提到: 这并不意味着
noexcept
是无用的。编译器将注释
隐式生成类的成员函数(构造函数,
使用noexcept
复制和移动赋值和析构函数),如下所示
适当的,STL组件将查询此注释。
该功能将启用显著的优化(通过使用move)
构造函数),即使您不会看到单个noexcept
关键字。
当编译器用noexcept
注释函数时,它会这样做
正确(析构函数除外),因此不存在某些
无异常移动构造函数将抛出
(强调矿山)来自[除了.spec]: 14-[…]如果
f
是[…]一个隐式声明的默认构造函数[…]f
允许所有异常,如果任何函数直接调用它
调用允许所有异常,如果每个函数都直接调用,则f
具有异常规范noexcept(true)
调用不允许任何异常。[……]
Aggregate
的隐式声明的默认构造函数直接调用允许所有异常的ClassThatMayThrowInCtor::ClassThatMayThrowInCtor()
,因此Aggregate::Aggregate()
允许所有异常,而不是noexcept来自[除了.spec]:
14-[…]如果f
是[…]一个隐式声明的默认构造函数[…]f
允许所有异常,如果任何函数直接调用它
调用允许所有异常,如果每个函数都直接调用,则f
具有异常规范noexcept(true)
调用不允许任何异常。[……]
Aggregate
的隐式声明的默认构造函数直接调用允许所有异常的ClassThatMayThrowInCtor::ClassThatMayThrowInCtor()
,因此Aggregate::Aggregate()
允许所有异常,而不是noexcept您可以在编译时对此进行检查。在下面的程序中,B的默认构造函数不是noexcept
:
struct A {
A() {
throw 0;
}
};
struct B {
A a;
};
static_assert(noexcept(B{}), "");
int main() {
return 0;
}
此程序无法编译,因为静态断言失败。您可以在编译时检查此问题。在下面的程序中,B的默认构造函数不是noexcept
:
struct A {
A() {
throw 0;
}
};
struct B {
A a;
};
static_assert(noexcept(B{}), "");
int main() {
return 0;
}
此程序无法编译,因为静态断言
失败。“在某些情况下,在C++14中,编译器可能会生成一个不例外的默认ctor”-请添加一个支持that@DavidHaim找到一个有效的参考是这个问题的重点(然后解释它)。@hauron,但你是在做陈述,不是在问。如果您没有任何引用,请以不同的方式提问,例如“是否允许编译器生成noexcept…”@DavidHaim注意,您可以始终使用noexcept(聚合{})
来查找特定类型。但当然,这只演示了编译器的行为,而不是标准要求。“在C++14中的某些情况下,编译器可能会生成一个默认的ctor,该ctor是noexcept”-请添加一个支持that@DavidHaim找到一个有效的参考是这个问题的重点(然后解释它)。@hauron,但你是在做陈述,不是在问。如果您没有任何引用,请以不同的方式提问,例如“是否允许编译器生成noexcept…”@DavidHaim注意,您可以始终使用noexcept(聚合{})
来查找特定类型。但当然,这只是演示编译器行为,而不是标准要求。