ふときがつくと、noexcept operatorなるものが追加されていた。これは、オペランドの式が、例外を投げそうな式を含む場合、falseを返す演算子である。結果はもちろん、定数だ。つまり、メタプログラミングに使える。オペランドの式は、評価されない。
void f() noexcept; void g() ; noexcept( f() ) ; // true noexcept( g() ) ; // false noexcept( throw 0 ) ; // false // ポリモーフィック型 struct Base { virtual void f() {} } ; struct Derived : Base { } ; Base base ; noexcept( dynamic_cast<Derived &>(base) ) ; // false noexcept( typeid(base) ) ; // false
たとえ、式を評価した結果、絶対に例外を投げることがなかったとしても、例外を投げる可能性のある式を含む場合、falseになる。たとえ、暗黙的にであれ、falseとなる。
// new式は例外を投げる可能性のある関数を呼ぶ。 noexcept( new int ) ; // false // 例外を投げることはないが、throwを「含む」のでfalse noexcept( true ? 0 : throw 0 ) ; // false
基本的には、exception specificationで、noexceptかnoexcept(true)が指定されているような、明示的な関数呼び出しの式ぐらいしか、trueにならない。実用上も、メタプログラミングで、ある関数が(演算子のオーバーロードも含めて)noexcept指定されているかどうか調べるのに使うことを想定しているのだろう。
否定疑問文って分かりにくいですよね。
ReplyDelete> noexcept( true : 0 : throw 0 ) ; // false
ReplyDeleteこれって
noexcept( true ? 0 : throw 0 ) ;
こーじゃね?
> noexcept( true ? 0 : throw 0 ) ;
ReplyDeleteおっと、修正