ওভারলোড রেজোলিউশনটি তখনই ঘটে যখন আপনি (ক) আপনি কোনও ফাংশন / অপারেটরের নাম কল করছেন বা (খ) এটিকে একটি স্বাক্ষর সহ একটি পয়েন্টারে (ফাংশন বা সদস্য ফাংশন করতে) কাস্ট করছেন।
এখানেও ঘটছে না।
std::function
তার স্বাক্ষরের সাথে সামঞ্জস্যপূর্ণ যে কোনও বস্তু গ্রহণ করে । এটি বিশেষভাবে কোনও ফাংশন পয়েন্টার গ্রহণ করে না। (একটি ল্যাম্বডা একটি স্ট্যান্ড ফাংশন নয়, এবং একটি স্ট্যান্ড ফাংশন ল্যাম্বডা নয়)
এখন আমার হোমব্রু ফাংশনের রূপগুলিতে, স্বাক্ষরের জন্য R(Args...)
আমি R(*)(Args...)
ঠিক এই কারণে একটি যুক্তি (একটি সঠিক মিল) গ্রহণ করি । তবে এর অর্থ এটি "সামঞ্জস্যপূর্ণ" স্বাক্ষরের উপরে "সঠিক মিল" স্বাক্ষরগুলিকে উন্নীত করে।
মূল সমস্যাটি হ'ল একটি ওভারলোড সেটটি কোনও সি ++ অবজেক্ট নয়। আপনি একটি ওভারলোড সেটটির নাম রাখতে পারেন, তবে আপনি এটিকে "স্থানীয়ভাবে" পাস করতে পারবেন না।
এখন, আপনি এই জাতীয় ফাংশনের সিউডো-ওভারলোড সেট তৈরি করতে পারেন:
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
#define OVERLOADS_OF(...) \
[](auto&&...args) \
RETURNS( __VA_ARGS__(decltype(args)(args)...) )
এটি একটি একক সি ++ অবজেক্ট তৈরি করে যা কোনও ফাংশন নামে ওভারলোড রেজোলিউশন করতে পারে।
ম্যাক্রোগুলি প্রসারিত করে আমরা পাই:
[](auto&&...args)
noexcept(noexcept( baz(decltype(args)(args)...) ) )
-> decltype( baz(decltype(args)(args)...) )
{ return baz(decltype(args)(args)...); }
যা লিখতে বিরক্তিকর। একটি সহজ, সামান্য কম দরকারী, সংস্করণ এখানে:
[](auto&&...args)->decltype(auto)
{ return baz(decltype(args)(args)...); }
আমাদের কাছে একটি ল্যাম্বডা রয়েছে যা বহু সংখ্যক আর্গুমেন্ট গ্রহণ করে, তারপরে নিখুঁতভাবে এগুলিকে এগিয়ে দেয় baz
।
তারপর:
class Bar {
std::function<void()> bazFn;
public:
Bar(std::function<void()> fun = OVERLOADS_OF(baz)) : bazFn(fun){}
};
কাজ করে। আমরা ওভারলোড রেজোলিউশনটি যে ল্যাম্বডায় সংরক্ষণ করি তাতে সরাসরি ওভারলোড সেটটি fun
পাস করার পরিবর্তে fun
(যা এটি সমাধান করতে পারে না) স্থির করে।
সি ++ ভাষায় কোনও অপারেশন সংজ্ঞায়িত করার জন্য কমপক্ষে একটি প্রস্তাব এসেছে যা কোনও ফাংশন নামকে ওভারলোড সেট অবজেক্টে রূপান্তর করে। এ জাতীয় মানক প্রস্তাবটি স্ট্যান্ডার্ড না হওয়া পর্যন্ত OVERLOADS_OF
ম্যাক্রো কার্যকর।
আপনি আরও একধাপ এগিয়ে যেতে এবং কাস্ট-টু-সামঞ্জস্যপূর্ণ-ফাংশন-পয়েন্টারটি সমর্থন করতে পারেন।
struct baz_overloads {
template<class...Ts>
auto operator()(Ts&&...ts)const
RETURNS( baz(std::forward<Ts>(ts)...) );
template<class R, class...Args>
using fptr = R(*)(Args...);
//TODO: SFINAE-friendly support
template<class R, class...Ts>
operator fptr<R,Ts...>() const {
return [](Ts...ts)->R { return baz(std::forward<Ts>(ts)...); };
}
};
কিন্তু এটি অবসন্নতা পেতে শুরু হয়।
সরাসরি উদাহরণ ।
#define OVERLOADS_T(...) \
struct { \
template<class...Ts> \
auto operator()(Ts&&...ts)const \
RETURNS( __VA_ARGS__(std::forward<Ts>(ts)...) ); \
\
template<class R, class...Args> \
using fptr = R(*)(Args...); \
\
template<class R, class...Ts> \
operator fptr<R,Ts...>() const { \
return [](Ts...ts)->R { return __VA_ARGS__(std::forward<Ts>(ts)...); }; \
} \
}