2012-12-22 1 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 함수인지 여부를 확실히 알고 있습니다. noexcept 네스 선언을 완전히 무시했을 때 내가 작성한 방식으로 test3을 쓸 수 있습니까?

표준이 이에 대해 구체적인 내용을 말해야합니까?

답변

2

C++ 17에서는 noexcept이 마지막으로 유형 시스템에 추가됩니다. 비 noexcept 함수에 대한 포인터는 noexcept 함수의 포인터로 암시 적으로 변환 될 수 없습니다. (그러나 다른 방법은 허용됩니다).

clang 3.9.0을 -std=c++1z으로, g ++ 7.0을 -std=c++17으로 변경하려면 test3(f1);을 거부하십시오.

6

C++ 11 표준의 15.4.13 절에는 "예외 사양은 함수 유형의 일부로 간주되지 않습니다"라고 나와 있습니다.

관련 문제