2014-05-21 2 views
6

테스트, 왜이 코드는 컴파일되지 않습니다재귀 noexcept 사양 g ++ 4.9 및 그 소리 3.4와

namespace { 

template<typename T> 
constexpr auto f(T && t) noexcept { 
    return true; 
} 

template<typename T> 
constexpr auto f_helper(T && t) noexcept(noexcept(f(t))) { 
    return f(t); 
} 

template<typename T, typename... Ts> 
constexpr auto f_helper(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
    return f(ts...); 
} 

template<typename T, typename... Ts> 
constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f_helper(ts...))) { 
    return f(ts...); 
} 

} // namespace 

int main() { 
    f(true, 0, 5u); 
} 

f_helper 기능을 정의 할 필요가 없습니다, 이 경우에는 decltype 방식으로 지정된 올바른 반환 유형이 있어야합니다.

첫 번째 코드도 1 또는 2 개의 인수로 컴파일되지만 3 회 이상 호출하면 해당 함수를 호출 할 때 오류가 발생합니다. 첫 번째 코드에 대한 연타 에러는 다음 이름 선언

source/main.cpp:9:59: error: call to function 'f' that is neither visible in the template definition nor 
     found by argument-dependent lookup 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
                   ^
source/main.cpp:9:17: note: in instantiation of exception specification for 'f<bool, int, unsigned int>' 
     requested here 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
        ^
source/main.cpp:16:3: note: in instantiation of function template specialization '<anonymous 
     namespace>::f<bool, int, unsigned int>' requested here 
       f(true, 0, 5u); 
       ^
source/main.cpp:9:17: note: 'f' should be declared prior to the call site 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
        ^
1 error generated. 
+0

4 개의 매개 변수를 f에 전달하면 도우미가있는 버전은 컴파일되지 않습니다 (http://coliru.stacked-crooked.com/a/126cee2269269e96). –

답변

5

3.3.2/1 포인트는 완전한 선언자 (8 절) 직후 및 초기화하기 전에 (있는 경우) ...

예외 지정은 구문 상 선언 자의 일부입니다. 따라서, 함수 이름은 자체의 예외 스펙 내에서 범위 내에 있지 않습니다.

+0

기술적으로 실제로이 함수를 재귀 적으로 호출하지는 않지만 궁극적으로 단일 인수 함수 정의를 호출하는 동일한 템플릿에서 생성 된 완전히 다른 함수를 호출하려고합니다. 그게 날 도와 줄 수 있니? –

+1

해당 기능 템플리트의 이름은 사용하려는 지점에서 범위 내에 있지 않습니다. –

+0

@DavidStone 그러나 ADL을 통해 찾을 수 있다고 생각하십니까? 해킹까지 열리는데, 여기에서는 동일한'네임 스페이스 '의 가짜 인수로'템플릿'함수 구현을 만들고, 구현 측면에서 공용 인터페이스를 정의합니다. 이것이 작동하는지 확실하지 않습니다. – Yakk