আমি এটি সবচেয়ে মার্জিত সমাধান বলে মনে করি (এবং এটি সর্বোত্তমভাবে এগিয়ে দেওয়া হয়েছে):
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
template<size_t N>
struct Apply {
template<typename F, typename T, typename... A>
static inline auto apply(F && f, T && t, A &&... a)
-> decltype(Apply<N-1>::apply(
::std::forward<F>(f), ::std::forward<T>(t),
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
))
{
return Apply<N-1>::apply(::std::forward<F>(f), ::std::forward<T>(t),
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
);
}
};
template<>
struct Apply<0> {
template<typename F, typename T, typename... A>
static inline auto apply(F && f, T &&, A &&... a)
-> decltype(::std::forward<F>(f)(::std::forward<A>(a)...))
{
return ::std::forward<F>(f)(::std::forward<A>(a)...);
}
};
template<typename F, typename T>
inline auto apply(F && f, T && t)
-> decltype(Apply< ::std::tuple_size<
typename ::std::decay<T>::type
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t)))
{
return Apply< ::std::tuple_size<
typename ::std::decay<T>::type
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t));
}
ব্যবহারের উদাহরণ:
void foo(int i, bool b);
std::tuple<int, bool> t = make_tuple(20, false);
void m()
{
apply(&foo, t);
}
দুর্ভাগ্যক্রমে জিসিসি (কমপক্ষে 6.6) "দুঃখিত, অবিহিত: ম্যাংলিং ওভারলোড" (এর সহজ অর্থ যে সংকলকটি এখনও পুরোপুরি সি ++ 11 স্পেসটি কার্যকরভাবে প্রয়োগ করে না), এবং যেহেতু এটি বৈকল্পিক টেম্পলেটগুলি ব্যবহার করে, এটি অভ্যাস করবে না এমএসভিসিতে কাজ করুন, সুতরাং এটি কম-বেশি অকেজো। যাইহোক, একবার স্পষ্ট সমর্থন করে এমন একটি সংকলক উপস্থিত থাকলে এটি সেরা পদ্ধতির আইএমএইচও হবে। (দ্রষ্টব্য: এটির সংশোধন করা এতটা কঠিন নয় যাতে আপনি জিসিসিতে ঘাটতিগুলি সমাধান করতে পারেন, বা এটি বুস্ট প্রিপ্রসেসর দিয়ে প্রয়োগ করতে পারেন, তবে এটি কমনীয়তা নষ্ট করে দেয়, তাই এটি আমি পোস্ট করছি এমন সংস্করণ))
জিসিসি 4.7 এখন এই কোডটি ঠিকঠাক সমর্থন করে।
সম্পাদনা করুন: যথাযথ রেফারেন্স ফর্মটি সমর্থন করার জন্য প্রকৃত ফাংশন কলের চারপাশে এগিয়ে যুক্ত করা হয়েছে * এটি আপনি যদি ঝাঁকুনি ব্যবহার করছেন (বা অন্য কেউ যদি বাস্তবে এটি যোগ করার আশেপাশে থাকে)।
সম্পাদনা: অ-সদস্য প্রয়োগ ফাংশনটির শরীরে ফাংশন অবজেক্টের আশেপাশে নিখোঁজ যুক্ত করা হয়েছে। অনুপস্থিত যে এটি অনুপস্থিত ছিল তা দেখানোর জন্য ফিডবাককে ধন্যবাদ।
সম্পাদনা করুন: এবং এখানে C ++ 14 সংস্করণটি কেবলমাত্র খুব সুন্দর হওয়ার কারণে (আসলে এখনও সংকলন করে না):
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
template<size_t N>
struct Apply {
template<typename F, typename T, typename... A>
static inline auto apply(F && f, T && t, A &&... a) {
return Apply<N-1>::apply(::std::forward<F>(f), ::std::forward<T>(t),
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
);
}
};
template<>
struct Apply<0> {
template<typename F, typename T, typename... A>
static inline auto apply(F && f, T &&, A &&... a) {
return ::std::forward<F>(f)(::std::forward<A>(a)...);
}
};
template<typename F, typename T>
inline auto apply(F && f, T && t) {
return Apply< ::std::tuple_size< ::std::decay_t<T>
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t));
}
এখানে সদস্য ফাংশনগুলির জন্য একটি সংস্করণ রয়েছে (খুব বেশি পরীক্ষিত নয়!):
using std::forward; // You can change this if you like unreadable code or care hugely about namespace pollution.
template<size_t N>
struct ApplyMember
{
template<typename C, typename F, typename T, typename... A>
static inline auto apply(C&& c, F&& f, T&& t, A&&... a) ->
decltype(ApplyMember<N-1>::apply(forward<C>(c), forward<F>(f), forward<T>(t), std::get<N-1>(forward<T>(t)), forward<A>(a)...))
{
return ApplyMember<N-1>::apply(forward<C>(c), forward<F>(f), forward<T>(t), std::get<N-1>(forward<T>(t)), forward<A>(a)...);
}
};
template<>
struct ApplyMember<0>
{
template<typename C, typename F, typename T, typename... A>
static inline auto apply(C&& c, F&& f, T&&, A&&... a) ->
decltype((forward<C>(c)->*forward<F>(f))(forward<A>(a)...))
{
return (forward<C>(c)->*forward<F>(f))(forward<A>(a)...);
}
};
// C is the class, F is the member function, T is the tuple.
template<typename C, typename F, typename T>
inline auto apply(C&& c, F&& f, T&& t) ->
decltype(ApplyMember<std::tuple_size<typename std::decay<T>::type>::value>::apply(forward<C>(c), forward<F>(f), forward<T>(t)))
{
return ApplyMember<std::tuple_size<typename std::decay<T>::type>::value>::apply(forward<C>(c), forward<F>(f), forward<T>(t));
}
// Example:
class MyClass
{
public:
void foo(int i, bool b);
};
MyClass mc;
std::tuple<int, bool> t = make_tuple(20, false);
void m()
{
apply(&mc, &MyClass::foo, t);
}