如何按类型从std :: tuple获取元素

Dan*_*tov 4 c++ c++11

我有一组类A,B,C,我希望按类型fe的通用代码访问它们的实例

template<typename T>
newObject()
{
    return m_storage->getNew();
}
Run Code Online (Sandbox Code Playgroud)

其中m_storage是A或B或C的实例,取决于T.

所以我提出了std :: tuple,但是有问题因为我无法按类型从元组中获取元素.

std::tuple<A,B,C> m_tpl;
template<typename T>
newObject()
{
    return m_tpl.get<T>().getNew();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?这可能吗?

谢谢.

PS:我不想为每种类型编写newObject的特化.:-)

awe*_*oon 16

是C++ 14关于从类型中获取元组值的草案.

但是在C++ 14出现之前,你可以写下面的内容:

namespace detail
{

template <class T, std::size_t N, class... Args>
struct get_number_of_element_from_tuple_by_type_impl
{
    static constexpr auto value = N;
};

template <class T, std::size_t N, class... Args>
struct get_number_of_element_from_tuple_by_type_impl<T, N, T, Args...>
{
    static constexpr auto value = N;
};

template <class T, std::size_t N, class U, class... Args>
struct get_number_of_element_from_tuple_by_type_impl<T, N, U, Args...>
{
    static constexpr auto value = get_number_of_element_from_tuple_by_type_impl<T, N + 1, Args...>::value;
};

} // namespace detail

template <class T, class... Args>
T get_element_by_type(const std::tuple<Args...>& t)
{
    return std::get<detail::get_number_of_element_from_tuple_by_type_impl<T, 0, Args...>::value>(t);
}

int main()
{
    int a = 42;

    auto t = std::make_tuple(3.14, "Hey!", std::ref(a));

    get_element_by_type<int&>(t) = 43;

    std::cout << a << std::endl;

    // get_element_by_type<char>(t); // tuple_element index out of range

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*kov 5

一个简单的可变参数 mixin 容器就可以解决这个问题:

template < typename T > struct type_tuple_value 
{ 
    T value; 
    type_tuple_value ( T&& arg ) : value(std::forward<T>(arg)) {}
};

template < typename ...T > struct type_tuple : type_tuple_value<T>...
{
    template < typename ...Args > type_tuple ( Args&&... args ) :
    type_tuple_value<T>(std::forward<T>(args))... {}
    template < typename U > U& get() { return type_tuple_value<U>::value; }
    template < typename U > const U& get() const { return type_tuple_value<U>::value; }
};
Run Code Online (Sandbox Code Playgroud)

例子