मैं अन्य उत्तर है, जो एक आवरण है कि functor के लिए मानकों की सही संख्या गुजरता बनाने के लिए प्रस्ताव में से एक ने प्रेरित हुआ:
template<typename L>
struct OptionalWrapper {
OptionalWrapper(L l) : lambda{std::move(l)} {}
void operator()(std::string body, std::string subject, std::string header) const {
call(lambda, body, subject, header);
}
private:
template<typename T>
auto call(T& l, std::string body, std::string subject, std::string header) const
-> decltype(l(body, subject, header))
{
return l(body, subject, header);
}
template<typename T>
auto call(T& l, std::string body, std::string subject, std::string) const
-> decltype(l(body, subject))
{
return l(body, subject);
}
template<typename T>
auto call(T& l, std::string body, std::string, std::string) const
-> decltype(l(body))
{
return l(body);
}
L lambda;
};
template<typename L>
auto makeOptionalWrapper(L l) { return OptionalWrapper<L>{std::move(l)}; }
फिर, उस तरह अपने आवरण का उपयोग करें। मुझे यह समाधान बहुत अच्छा लगता है, और सोचा कि मैं एक सामान्य टेम्पलेटेड रैपर बनाने की कोशिश करूंगा, जहां तर्कों की संख्या हार्डकोड नहीं की जाती है।
#include <string>
#include <functional>
#include <iostream>
struct WrapperHelp
{
template
< typename L
, typename Tuple
, std::size_t... Is
, typename... Ts
>
static auto apply(L&& l, Tuple t, std::index_sequence<Is...>, Ts&&... ts)
-> decltype(l(std::get<Is>(t)...))
{
return l(std::get<Is>(t)...);
}
template
< typename L
, typename Tuple
, std::size_t... Is
, typename T1
, typename... Ts
>
static auto apply(L&& l, Tuple t, std::index_sequence<Is...>, T1&& t1, Ts&&... ts)
-> decltype(WrapperHelp::apply(std::forward<L>(l), std::forward_as_tuple(std::get<Is>(t)..., t1), std::make_index_sequence<sizeof...(Is) +1 >(), ts...))
{
return WrapperHelp::apply(std::forward<L>(l), std::forward_as_tuple(std::get<Is>(t)..., t1), std::make_index_sequence<sizeof...(Is) + 1>(), ts...);
}
};
template<typename L>
struct OptionalWrapper {
public:
OptionalWrapper(L l) : lambda{std::move(l)} {}
template<typename... Ts>
void operator()(Ts&&... ts) const
{
WrapperHelp::apply(lambda, std::tuple<>(), std::index_sequence<>(), std::forward<Ts>(ts)...);
}
private:
L lambda;
};
template<typename L>
auto makeOptionalWrapper(L l) { return OptionalWrapper<L>{std::move(l)}; }
template<class F>
void loadData(OptionalWrapper<F>&& callback)
{
std::string body = "body";
std::string subject = "subject";
std::string header = "header";
double lol = 2.0;
callback(body, subject, header, lol);
}
template<typename L>
void loadData(L callback)
{
loadData(makeOptionalWrapper(std::move(callback)));
}
int main() {
//apply(std::tuple<double>(2), std::tuple<double>(2));
loadData([](auto&& body) {
std::cout << body << std::endl;
});
loadData([](auto&& body, auto&& subject) {
std::cout << body << " " << subject << std::endl;
});
loadData([](auto&& body, auto&& subject, auto&& header) {
std::cout << body << " " << subject << " " << header << std::endl;
});
loadData([](auto&& body, auto&& subject, auto&& header, auto&& lol) {
std::cout << body << " " << subject << " " << header << " " << lol << std::endl;
});
return 0;
}
यह "वैकल्पिक" मानकों के किसी भी संख्या के साथ, किसी भी कार्य के लिए काम करना चाहिए, और पैरामीटर के किसी भी प्रकार के साथ: यहाँ है कि मैं क्या के साथ आया है। यह सबसे सुंदर कोड नहीं है, लेकिन मुझे उम्मीद है कि विचार स्पष्ट है और कुछ का उपयोग :)
Live example
सिर्फ क्यों ओवरलोड नहीं की जा सकता है? या बस अन्य दो पैरामीटर – Mgetz
@Mgetz को अनदेखा करें क्योंकि मैं एक बार फिर से इस मुद्दे का सामना कर सकता हूं जब मेरे पास 3 से अधिक तर्क होंगे, और मेरे पास अधिक अधिभार है, यूग्लियर और कम पठनीय मेरा कोड बन जाता है। –
मुझे लगता है कि कुछ कारण हैं कि आप तर्क को 'स्ट्रक्चर' में पास नहीं करना चाहते हैं? –