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(聚合{})
来查找特定类型。但当然,这只是演示编译器行为,而不是标准要求。