関数呼び出し間の伝播をテストするために次のコードを作成しましたが、noexcept
思ったように機能しないようです。GCC 4.7.2 では、関数は、noexcept
直接またはテンプレート特殊化引数として渡された場合にのみ効果的にテストできます。ただし、テンプレート化された関数に引数として渡された場合、または通常の関数への関数ポインターとして渡された場合はそうではありません。その関数がその仮パラメーターを として宣言している場合でもnoexcept
。コードは次のとおりです。
#include <iostream>
#define test(f) \
std::cout << __func__ << ": " #f " is " \
<< (noexcept(f()) ? "" : "not ") \
<< "noexcept\n";
template <void(*f)()>
static inline void test0() {
test(f);
}
template <typename F>
static inline void test1(F f) {
test(f);
}
static inline void test2(void(*f)()) {
test(f);
}
static inline void test3(void(*f)()noexcept) {
test(f);
}
void f1() {}
void f2() noexcept {}
int main() {
test(f1);
test(f2);
test0<f1>();
test0<f2>();
test1(f1);
test1(f2);
test2(f1);
test2(f2);
test3(f1);
test3(f2);
return 0;
}
出力は次のとおりです。
main: f1 は noexcept ではありません メイン: f2 は noexcept です test0: f は noexcept ではありません test0: f は noexcept です test1: f は noexcept ではありません test1: f は noexcept ではありません test2: f は noexcept ではありません test2: f は noexcept ではありません test3: f は noexcept ではありません test3: f は noexcept ではありません
noexcept
ネスが他の場合に伝播されないのはなぜですか? の場合、test1
関数全体が の適切な型で「インスタンス化」されF
、コンパイラはその時点で F がnoexcept
関数であるかどうかを確実に認識します。ness宣言が完全に無視されているのに、なぜ私が書いtest3
たように書くことができるのでしょうか?noexcept
標準はこれについて具体的に何かを言う必要がありますか?