সম্পাদনা প্রদত্ত যে একটি খালি বৈকল্পিক ( std::variant<>
) অসুস্থ (অনুযায়ী গঠিত হয় cppreference ) এবং যে ব্যবহার করা উচিত std::variant<std::monostate>
পরিবর্তে, আমি উত্তর (ক যোগ পরিবর্তিত করে থাকেন tuple2variant()
খালি tuple জন্য বিশেষজ্ঞতা) ক্ষেত্রে সমর্থন করার জন্য জন্য ধরনের তালিকাতে V1
বা V2
খালি।
এটি একটি সামান্য decltype()
প্রলাপ কিন্তু ... যদি আপনি নিম্নলিখিত হিসাবে কোনও সহায়ক ফিল্টার দম্পতি ঘোষণা করেন
template <bool B, typename T>
constexpr std::enable_if_t<B == std::is_arithmetic_v<T>, std::tuple<T>>
filterArithm ();
template <bool B, typename T>
constexpr std::enable_if_t<B != std::is_arithmetic_v<T>, std::tuple<>>
filterArithm ();
এবং ভেরিয়েন্ট ফাংশন (একটি ফাঁকা এড়ানোর জন্য খালি tuples জন্য একটি বিশেষীকরণ সহ std::variant
)
std::variant<std::monostate> tuple2variant (std::tuple<> const &);
template <typename ... Ts>
std::variant<Ts...> tuple2variant (std::tuple<Ts...> const &);
আপনার ক্লাসটি কেবল (?) হয়ে যায়
template <typename ... Ts>
struct TheAnswer<std::variant<Ts...>>
{
using V1 = decltype(tuple2variant(std::declval<
decltype(std::tuple_cat( filterArithm<true, Ts>()... ))>()));
using V2 = decltype(tuple2variant(std::declval<
decltype(std::tuple_cat( filterArithm<false, Ts>()... ))>()));
};
আপনি যদি আরও জেনেরিক কিছু চান (যদি আপনি std::arithmetic
কোনও টেমপ্লেট প্যারামিটার হিসাবে পাস করতে চান ), আপনি filterArithm()
টেমপ্লেট-টেম্পলেট ফিল্টার প্যারামিটার F
(পুনঃনামকরণ filterType()
) পাস করে ফাংশনটি পরিবর্তন করতে পারেন
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B == F<T>::value, std::tuple<T>>
filterType ();
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B != F<T>::value, std::tuple<>>
filterType ();
TheAnswer
বর্গ পরিণত
template <typename, template <typename> class>
struct TheAnswer;
template <typename ... Ts, template <typename> class F>
struct TheAnswer<std::variant<Ts...>, F>
{
using V1 = decltype(tuple2variant(std::declval<decltype(
std::tuple_cat( filterType<F, true, Ts>()... ))>()));
using V2 = decltype(tuple2variant(std::declval<decltype(
std::tuple_cat( filterType<F, false, Ts>()... ))>()));
};
এবং TA
ঘোষণা এছাড়াও গ্রহণstd::is_arithmetic
using TA = TheAnswer<std::variant<bool, char, std::string, int, float,
double, std::vector<int>>,
std::is_arithmetic>;
নীচে std::is_arithmetic
প্যারামিটার এবং V2
খালি কেস সহ একটি সম্পূর্ণ সংকলন উদাহরণ রয়েছে
#include <tuple>
#include <string>
#include <vector>
#include <variant>
#include <type_traits>
std::variant<std::monostate> tuple2variant (std::tuple<> const &);
template <typename ... Ts>
std::variant<Ts...> tuple2variant (std::tuple<Ts...> const &);
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B == F<T>::value, std::tuple<T>>
filterType ();
template <template <typename> class F, bool B, typename T>
constexpr std::enable_if_t<B != F<T>::value, std::tuple<>>
filterType ();
template <typename, template <typename> class>
struct TheAnswer;
template <typename ... Ts, template <typename> class F>
struct TheAnswer<std::variant<Ts...>, F>
{
using V1 = decltype(tuple2variant(std::declval<decltype(
std::tuple_cat( filterType<F, true, Ts>()... ))>()));
using V2 = decltype(tuple2variant(std::declval<decltype(
std::tuple_cat( filterType<F, false, Ts>()... ))>()));
};
int main ()
{
using TA = TheAnswer<std::variant<bool, char, std::string, int, float,
double, std::vector<int>>,
std::is_arithmetic>;
using TB = TheAnswer<std::variant<bool, char, int, float, double>,
std::is_arithmetic>;
using VA1 = std::variant<bool, char, int, float, double>;
using VA2 = std::variant<std::string, std::vector<int>>;
using VB1 = VA1;
using VB2 = std::variant<std::monostate>;
static_assert( std::is_same_v<VA1, TA::V1> );
static_assert( std::is_same_v<VA2, TA::V2> );
static_assert( std::is_same_v<VB1, TB::V1> );
static_assert( std::is_same_v<VB2, TB::V2> );
}
Types...
ভিতরেstd::variant
মত সরাসরি এই ?