tuple - get_or辅助函数

时间:2013-07-09 05:57:34

标签: c++ tuples template-meta-programming boost-fusion

我需要一个元组辅助函数,如果元组中不存在请求的类型,它将返回默认的构造null类型。

e.g。

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);

我想我需要一些增强融合魔法,但我还没弄明白。有什么建议吗?

1 个答案:

答案 0 :(得分: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都是必需的,因为元函数会区分tupletuple &