2011-01-20 46 views
3

我想寫一個通用的過濾函數,在多維數組(任意級別)的給定採樣座標處執行線性插值。爲此,我需要一個遞歸函數模板,遍歷數組的所有維度,直到它遇到一個值及其相關類型。我使用boost :: enable_if來檢測何時停止遍歷維度。它工作正常,直到我試圖「滲透」返回值/類型到最頂層的函數。爲此,我試圖使用C++ 0x類型推斷,但它似乎沒有與boost :: enable_if良好混合。C++ 0x類型推斷使用boost :: enable_if messes

予分離的問題降低到什麼如下:

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的返回值,即使它被指示使用測試< T,I - 1>。任何想法爲什麼發生這種行爲?現在,它認爲我只是把整個事情變成一個仿函數...

回答

4

問題是你傳遞了一個T()(和T)到decltype。類型不折疊。如果將返回表達式與傳遞給decltype的返回表達式進行比較,則顯然會顯示這一點 - 它們不一致。

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: test<T

return expression: test< typename T::value_type

當定義向前這樣的功能,用於定義返回類型decltype表達應該幾乎總是是完全一樣的實際返回的表達。

編輯:我需要補充的是,在實際情況下,您將不會傳遞左值,尤其是傳遞給模板,因爲您最終可能會得到不同的結果。

+0

我錯過了那個,非常感謝! – pmjobin 2011-01-20 23:52:00