Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
428 views
in Technique[技术] by (71.8m points)

c++ - How to get element from std::tuple by type

I have a set of classes A, B, C and I want to have access instances of them from generic code by type, f.e

template<typename T>
newObject()
{
    return m_storage->getNew();
}

where m_storage is instance of A or B or C, depends on T.

So I came up with std::tuple, but there is the problem because I can't get element from tuple by type.

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

Is there any way to do it?Is this possible?

Thanks.

PS: I don't want to write the specialisation of newObject for each type.:-)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a draft from C++14 about getting value from tuple by type.

But before C++14 will come, you could write something like below:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...