2010-06-24

noexcept operator

ふときがつくと、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指定されているかどうか調べるのに使うことを想定しているのだろう。

3 comments:

Anonymous said...

否定疑問文って分かりにくいですよね。

Anonymous said...

> noexcept( true : 0 : throw 0 ) ; // false

これって
noexcept( true ? 0 : throw 0 ) ;
こーじゃね?

江添亮 said...

> noexcept( true ? 0 : throw 0 ) ;
おっと、修正