2011-01-20 5 views
3

다차원 배열 (임의의 순위)에서 주어진 샘플링 좌표에서 선형 보간법을 수행하는 일반 필터링 함수를 작성하려고합니다. 이를 위해 값과 관련 유형에 도달 할 때까지 배열의 모든 차원을 처리하는 재귀 함수 템플릿이 필요합니다. 나는 boost :: enable_if를 사용하여 치수를 반복하는 것을 멈출 때를 감지한다. 최상위 함수에 반환 값/형식을 "여과"하려고 시도 할 때까지는 제대로 작동합니다. 이 목적을 위해 C++ 0x 형식 유추를 시도했지만 boost :: enable_if와 잘 어울리지 않는 것 같습니다.boost :: enable_if와의 C++ 0x 형식 추론이 엉망입니다

template< typename T, std::size_t I > 
auto test(const T &t) -> typename boost::enable_if_c< (I == 0), typename T::value_type >::type 
{ 
    return t[0]; 
} 

template< typename T, std::size_t I > 
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type 
{ 
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]); 
} 

컴파일러 (GCC 4.6)를 다음 코드로 불평 :

typedef std::array< std::array< float, 1 >, 1 > myarray; 
myarray ma; 
std::cout << typeid (test< myarray, 1 >(ma)).name() << std::endl; 

오류 메시지 :

error: conversion from 'boost::enable_if_c<true, float>::type' to non-scalar type 'boost::enable_if_c<true, std::array<float, 1u> >::type' requested 

그것을

나는 다음과 무슨 문제를 격리 decltype은 테스트에서 반환 값을 사용하는 것으로 보입니다. < T, I> 지시 받았음에도 불구하고 테스트 < T, I - 1>을 사용하십시오. 이 문제가 발생하는 이유는 무엇입니까? 지금 당장은 모든 것을 하나의 functor로 바꾸어 놓을 것이라고 생각합니다 ...

답변

4

문제는 decltype에 T() (와 T)를 전달한 것입니다. 유형이 접히지 않습니다. 반환 식을 decltype에 전달한 것과 비교하면 명확하게 나타납니다. 불일치합니다.

decltype: test<T

return expression: test< typename T::value_type

template< typename T, std::size_t I > 
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type 
{ 
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]); 
} 
순방향 이런 기능을 정의 리턴 유형을 정의하는데 사용되는 decltype 표현은 거의 항상 실제 리턴 발현과 정확하게 일치한다.

편집 : 실제로 결과가 달라질 수 있으므로 실제로는 lvalues, 특히 템플릿을 전달할 때 rvalues를 넘겨서는 안된다는 것을 추가해야합니다.

+0

나는 그 중 하나를 놓쳤다. 정말 고마워! – pmjobin