[英]How to get element from std::tuple by type
我有一組類A,B,C,我希望按類型fe的通用代碼訪問它們的實例
template<typename T>
newObject()
{
return m_storage->getNew();
}
其中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();
}
有沒有辦法做到這一點?這可能嗎?
謝謝。
PS:我不想為每種類型編寫newObject的特化。:-)
這是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;
}
一個簡單的可變混合容器可以解決這個問題:
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; }
};
如果您不喜歡模板,還可以使用constexpr函數計算類型的位置。
constexpr int count_first_falses() { return 0; }
template <typename... B>
constexpr int count_first_falses(bool b1, B... b)
{
if (b1) return 0;
else return 1 + count_first_falses(b...);
}
template <typename E, typename... T>
decltype(auto) tuple_get_by_type(const std::tuple<T...>& tuple)
{
return std::get<count_first_falses((std::is_same<T, E>::value)...)>(tuple);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.