मुझे लगता है कि यह सबसे सुरुचिपूर्ण समाधान है (और यह आशावादी रूप से अग्रेषित किया गया है):
#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);
}
दुर्भाग्य से जीसीसी (4.6 कम से कम) इसे "क्षमा करें, अकल्पित: प्रबंधनीय अधिभार" के साथ संकलित करने में विफल रहता है (जिसका सीधा अर्थ है कि कंपाइलर अभी तक पूरी तरह से सी ++ 11 कल्पना को लागू नहीं करता है), और चूंकि यह वैरेडिक टेम्प्लेट का उपयोग करता है, इसलिए यह अभ्यस्त नहीं है MSVC में काम करते हैं, इसलिए यह कमोबेश बेकार है। हालांकि, एक बार एक कंपाइलर है जो कल्पना का समर्थन करता है, यह सबसे अच्छा दृष्टिकोण आईएमएचओ होगा। (नोट: इसे संशोधित करना इतना कठिन नहीं है कि आप जीसीसी में कमियों के आसपास काम कर सकते हैं, या इसे बूस्ट प्रीप्रोसेसर के साथ लागू कर सकते हैं, लेकिन यह लालित्य को बर्बाद कर देता है, इसलिए यह वह संस्करण है जिसे मैं पोस्ट कर रहा हूं।)
GCC 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);
}