2012-12-22 18 views
7

我已經寫了下面的代碼來測試noexcept傳播跨函數調用,它似乎不工作,因爲我會想到的。在GCC 4.7.2中,一個函數可以直接或僅在作爲模板專用化參數傳遞時才能被有效地測試爲noexcept;但是不是作爲參數傳遞給模板化函數時,或作爲指向正常函數的函數指針 - 即使該函數將其形式參數聲明爲noexcept。下面的代碼:關於noexcept-ness的知識應該在傳遞函數指針時被轉發?

#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 is not noexcept 
main: f2 is noexcept 
test0: f is not noexcept 
test0: f is noexcept 
test1: f is not noexcept 
test1: f is not noexcept 
test2: f is not noexcept 
test2: f is not noexcept 
test3: f is not noexcept 
test3: f is not noexcept 

爲什麼noexcept岬未在其他情況下傳播?在test1的情況下,整個函數用適當類型的「實例化」F,編譯器當時知道F是否是noexcept函數。爲什麼可以按照我寫的方式編寫test3,當noexcept的聲明完全被忽略?

標準是否必須對此有具體的說明?

回答

2

在C++ 17中,最終將noexcept添加到類型系統中。指向非noexcept函數的指針不能隱式轉換爲指向noexcept函數的指針。 (但反過來也是允許的)。

鏗3.9.0與-std=c++1z和g ++ 7.0與-std=c++17,拒絕行test3(f1);

6

C++ 11標準的第15.4.13節指出「異常規範不被認爲是函數類型的一部分」。