7

関数呼び出し間の伝播をテストするために次のコードを作成しましたが、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

標準はこれについて具体的に何かを言う必要がありますか?

4

2 に答える 2