复制返回值和noexcept的省略

Mar*_*hrs 5 c++ optimization exception noexcept

我有一个这样的功能模板:

template <typename T>
constexpr auto myfunc() noexcept
{
    return T{};
}
Run Code Online (Sandbox Code Playgroud)

由于复制省略,此功能模板是否保证是noexcept?如果在构造函数中抛出异常,这是在函数内部还是外部发生?

Sam*_*hik 6

复制省略所做的就是消除实际的复制或移动.一切都发生"如果"事情发生而没有发生复制过程(当然除了复制本身).

构造发生在函数内部.复制省略不会改变这一点.它所做的只是消除实际的复制/移动(我是否重复自己?),因为函数的返回值被推回其调用者.

因此,如果类的默认构造函数抛出一个异常,noexcept则从高轨道中取出整个东西.

如果复制/移动构造函数抛出异常,因为复制/移动不会发生,所以一切都继续发生.

使用gcc 7.3.1,使用-std = c ++ 17编译:

template <typename T>
constexpr auto myfunc() noexcept
{
    return T{};
}

class xx {
public:

    xx() { throw "Foo"; }
};

int main()
{
    try {
        myfunc<xx>();
    } catch (...) {
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

terminate called after throwing an instance of 'char const*'
Run Code Online (Sandbox Code Playgroud)

现在,让我们混合它,并在复制和移动构造函数中抛出异常:

class xx {
public:

    xx() { }

    xx(xx &&) { throw "Foo"; }

    xx(const xx &) { throw "Baz"; }
};
Run Code Online (Sandbox Code Playgroud)

这没有例外.