विभाजित करने के लिए "आधुनिक" सी ++ में जिस तरह से, मैं एक प्रकार सूची है। अधिक सटीक होना, मेरा पूरा काम कर उदाहरण है:सबसे सुरुचिपूर्ण एक सी ++ TypeList
#include <iostream>
#include <type_traits>
template <typename... T> struct TypeList {};
// SplitTypeList<> implementation defined at the end of this post...
template <typename T>
void printType()
{
std::cout << "\n" << __PRETTY_FUNCTION__;
}
int main()
{
struct A
{
};
using typeList = TypeList<int, double, float, A, int>;
using splited_typeList = SplitTypeList<std::is_floating_point, typeList>;
using float_typeList = splited_typeList::predicate_is_true_typeList_type;
using other_typeList = splited_typeList::predicate_is_false_typeList_type;
printType<float_typeList>();
printType<other_typeList>();
}
प्रिंट:
g++ -std=c++17 typeList.cpp -o typeList; ./typeList
void printType() [with T = TypeList<double, float>]
void printType() [with T = TypeList<int, main()::A, int>]
मेरे सवाल: यदि आप एक संभव छोटी/अधिक सुरुचिपूर्ण समाधान की एक विचार है कि केवल सी ++ का उपयोग करता है (सी ++ 17 के साथ कोई समस्या नहीं) और एसटीएल? (मैं बूस्ट, हाना जैसे सहायक lib का उपयोग नहीं करना चाहता ...)।
(मेरे प्रेरणा: मैं, एक एक या दो पंक्तियों/सुपर सुरुचिपूर्ण समाधान याद आती है के रूप में मैं अन्य स्थानों में बड़े पैमाने पर इस कार्यक्षमता का उपयोग होगा नहीं करना चाहती)
मेरे वर्तमान कार्यान्वयन है:
namespace Details
{
template <template <typename> class PREDICATE,
typename... TYPELIST_PREDICATE_IS_TRUE,
typename... TYPELIST_PREDICATE_IS_FALSE>
constexpr auto splitTypeList(TypeList<TYPELIST_PREDICATE_IS_TRUE...>,
TypeList<TYPELIST_PREDICATE_IS_FALSE...>,
TypeList<>)
{
return std::make_pair(TypeList<TYPELIST_PREDICATE_IS_TRUE...>(),
TypeList<TYPELIST_PREDICATE_IS_FALSE...>());
}
template <template <typename> class PREDICATE,
typename... TYPELIST_PREDICATE_IS_TRUE,
typename... TYPELIST_PREDICATE_IS_FALSE,
typename T,
typename... TAIL>
constexpr auto splitTypeList(TypeList<TYPELIST_PREDICATE_IS_TRUE...>,
TypeList<TYPELIST_PREDICATE_IS_FALSE...>,
TypeList<T, TAIL...>)
{
if constexpr (PREDICATE<T>::value)
{
return splitTypeList<PREDICATE>(
TypeList<TYPELIST_PREDICATE_IS_TRUE..., T>(),
TypeList<TYPELIST_PREDICATE_IS_FALSE...>(),
TypeList<TAIL...>());
}
else
{
return splitTypeList<PREDICATE>(
TypeList<TYPELIST_PREDICATE_IS_TRUE...>(),
TypeList<TYPELIST_PREDICATE_IS_FALSE..., T>(),
TypeList<TAIL...>());
}
}
template <template <typename> class PREDICATE, typename... T>
constexpr auto splitTypeList(TypeList<T...>)
{
return splitTypeList<PREDICATE>(
TypeList<>(), TypeList<>(), TypeList<T...>());
}
}
template <template <typename> class PREDICATE, typename TYPELIST>
struct SplitTypeList;
template <template <typename> class PREDICATE, typename... TAIL>
struct SplitTypeList<PREDICATE, TypeList<TAIL...>>
{
using pair_type = decltype(
Details::splitTypeList<PREDICATE>(std::declval<TypeList<TAIL...>>()));
using predicate_is_true_typeList_type = typename pair_type::first_type;
using predicate_is_false_typeList_type = typename pair_type::second_type;
};
बस जिज्ञासा के लिए
, TypeList (आंद्रेई Alexandrescu, फरवरी 01, 2002) के लिए एक ऐतिहासिक सूचक: http://www.drdobbs.com/generic-programmingtypelists-and-applica/184403813
बहुत अच्छा समाधान (IMHO) हो सकता है। लेकिन क्यों '(शामिल करें & पी :: मूल्य) || (! शामिल करें &&! पी :: मूल्य) 'और न केवल' शामिल करें == पी :: मूल्य'? –
max66
@ max66 हाँ, यह आसान है, मैं बस एक बूलियन केवल मूड में था :) संपादित –
मुझे पता है ... मैं टेम्पलेट मेटा प्रोग्रामिंग केवल मूड में हूं; लेकिन आपका समाधान बहुत सरल, छोटा और (आईएमएचओ) बहुत ही सुरुचिपूर्ण है। – max66