सदस्य कार्य करने के लिए सूचक का आपके द्वारा उपयोग एक बुरा विचार है, यदि foo
ओवरलोड हो गया है, तो यह बहुत खराब हो जाता है (आपके पास एक foo है, लेकिन केवल एक नहीं)। वास्तव में कौन चाहता है "क्या आपके पास बिल्कुल एक फू है"? लगभग कोई नहीं।
यहाँ एक briefer संस्करण है:
template<class T>
using dot_foo_r = decltype(std::declval<T>().foo());
template<class T>
using can_foo = can_apply<dot_foo_r, T>;
जहां
namespace details {
template<template<class...>class, class, class...>
struct can_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;
अब, लेखन dot_foo_r
थोड़ा कष्टप्रद है।
constexpr
लैम्बडास के साथ हम इसे कम परेशान कर सकते हैं और इसे इनलाइन कर सकते हैं।
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
यह जरूरत RETURNS
मैक्रो, कम से कम जब तक @[](auto&&f)RETURNS(f())
को बैरी प्रस्तुत [](auto&&f)=>f()
के बराबर हो नहीं करता है।
हम तो can_invoke_f
, जो std::is_invokable
के constexpr
संस्करण है लिखें:
template<class F>
constexpr auto can_invoke(F&& f) {
return [](auto&&...args)->std::is_invokable<F(decltype(args)...)>{
return {};
};
}
यह हमें देता है:
if constexpr(
can_invoke([](auto&&var) RETURNS(var.foo()))(var)
) {
var.foo();
}
या का उपयोग करते हुए @ बैरी प्रस्तावित सी ++ 20 वाक्य रचना:
if constexpr(can_invoke(var=>var.foo())(var)) {
var.foo();
}
और हम कर रहे हैं।
चाल यह है कि RETURNS
मैक्रो (या =>
सी ++ 20 फीचर) हमें अभिव्यक्ति पर SFINAE करने देता है। लैम्ब्डा उस अभिव्यक्ति को मूल्य के रूप में ले जाने का एक आसान तरीका बन जाता है।
आप
[](auto&&var) ->decltype(var.foo()) { return var.foo(); }
लिख सकता है लेकिन मुझे लगता है RETURNS
इसके लायक है (और मैं मैक्रो पसंद नहीं है)।
[प्रासंगिक] (https://meta.stackoverflow.com/a/323382/2069064)। एक जवाब हो सकता है क्योंकि यहां कोई प्रतिस्थापन नहीं है, तो SFINAE कैसे हो सकता है? एक और जवाब हो सकता है क्योंकि यह विचार नहीं किया गया था क्योंकि प्रस्ताव हमेशा 'बूल' लेने के बारे में थे? – Barry
@ बररी ने उम्मीदवार को एक ऐसे रूप में संपादित किया जिसका स्पष्ट जवाब हो सकता है। मूल रूप से [इस तरह के उत्तर] के आधार पर कुछ के बारे में सोच रहा था (https://stackoverflow.com/a/6623089/4832499) –