2013-07-09 72 views
3

我需要一個元組助手函數,如果請求的類型不存在於元組中,它將返回一個默認構造的null類型。元組 - get_or幫助函數

例如

std::tuple<bool, int> tuple(true, 0); 

static_assert(std::is_same<decltype(get_or<double, std::nullptr_t>(tuple)), 
          std::nullptr_t>::value, ""); 
assert(get_or<double, std::nullptr_t>(tuple) == nullptr); 

我想我需要一些提升融合魔法,但我還沒有完全想通了。有什麼建議麼?

+0

你的第一行不應該編譯。你需要傳遞第二個構造函數參數。 – juanchopanza

+0

@juanchopanza - 我認爲第一行實際上是個問題。他希望能夠像這樣初始化元組,並將第二個參數設置爲默認值 – asafrob

+0

@asafrob Ah OK。問題出現的方式給我帶來了麻煩。沒有幫助函數可以解決編譯器錯誤。 – juanchopanza

回答

2

這裏是一個tuple_index助手我躺在附近,它返回std::tuple給定類型的索引。 (它可以很容易地調整與爲is_convertible這樣一個謂語工作。)

template< typename elem, typename tup, std::size_t offset = 0 > 
struct tuple_index 
    : std::integral_constant< std::size_t, offset > {}; 

template< typename elem, typename head, typename ... tail, std::size_t offset > 
struct tuple_index< elem, std::tuple< head, tail ... >, offset > 
    : std::integral_constant< std::size_t, tuple_index< elem, std::tuple< tail ... >, offset + 1 >::value > {}; 

template< typename elem, typename ... tail, std::size_t offset > 
struct tuple_index< elem, std::tuple< elem, tail ... >, offset > 
    : std::integral_constant< std::size_t, offset > {}; 

你可以建立在這樣的:

template< typename result, typename fallback, typename tuple > 
typename std::enable_if< tuple_index< result, typename std::decay<tuple>::type >::value 
         == std::tuple_size< typename std::decay<tuple>::type >::value, 
    fallback >::type 
get_or(tuple && t) { return {}; } 

template< typename result, typename fallback, typename tuple > 
typename std::enable_if< tuple_index< result, typename std::decay<tuple>::type >::value 
         != std::tuple_size< typename std::decay<tuple>::type >::value, 
    result >::type 
get_or(tuple && t) { 
    return std::get< tuple_index< result, typename std::decay<tuple>::type >::value > 
     (std::forward<tuple>(t)); 
} 

http://ideone.com/ZdoWI7

所有decay是必要的,因爲metafunctions歧視tupletuple &

+0

太好了!雖然我希望使用boost mpl或fusion更簡單的幫助函數? – ronag

+0

這已經很簡單了,只是由於我複製粘貼的「衰變」而變得冗長。你可以通過中介調度來分解它。我也懷疑「前鋒」在做什麼;我只是加了防守。 – Potatoswatter