को देखते हुए 2 प्रकार T
और U
मैं चाहे वह वस्तुओं के लिए उन (यानी के बीच operator *
कॉल करने के लिए संभव है पता लगाने के लिए चाहते हैं यह संभव t * u
लिखने के लिए जहां t
प्रकार T
की है और u
प्रकार U
)(पर विचार static_asserts) का पता लगाने के लिए कि क्या ऑपरेटर मौजूद है और ग में प्रतिदेय ++
मैं c++ detection idiom उपयोग कर रहा हूँ की है, लेकिन यह अभी तक अपने संकलक में उपलब्ध नहीं है के बाद से मैं इसे अपने आप की तरह इस
struct nonesuch {
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;
};
namespace detail {
template <class Default, class AlwaysVoid, template<class...> class Op, class... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};
template <class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
using value_t = std::true_type;
using type = Op<Args...>;
};
} // namespace detail
template <template<class...> class Op, class... Args>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
template< template<class...> class Op, class... Args >
constexpr bool is_detected_v = is_detected<Op, Args...>::value;
नहीं लागू किया डब्ल्यू मैं ऐसे सहायक है:
template <typename T, typename U>
using multiply = decltype(std::declval<T>() * std::declval<U>());
और पता लगाने के लिए कि क्या यह प्रतिदेय है मैं फोन
bool can_multiply = is_detected_v<multiply, T, U>
यह लगभग ठीक, उदाहरण के लिए इस प्रिंट है 1, उम्मीद 0 के रूप में
std::cout << is_detected_v<multiply, int, int> << std::endl;
std::cout << is_detected_v<multiply, std::vector<int>, std::vector<int>> << std::endl;
लेकिन अब मेरे पास कक्षा
template<typename T>
class A {
};
template<typename T>
A<T> operator*(const A<T>&, const A<T>&) {
static_assert(!std::is_same<bool, T>::value);
return A<T>();
}
यहां A<bool>
A<bool>
से गुणा नहीं किया जा सकता, लेकिन मेरे कोड का पता लगाता है कि यह संभव है
std::cout << is_detected_v<multiply, A<bool>, A<bool>> << std::endl; // 1
A<bool>() * A<bool>(); // does't compile
तो, मेरे सवाल, कैसे मेरे कोड तरीकों का पता नहीं लगा करने के लिए तय करने के लिए किया जाता है, जब वे बाहर static_asserted? मुझे लगता है कि मैं कुछ sfinae के साथ static_assert
को प्रतिस्थापित कर सकता हूं लेकिन मैं नहीं चाहता (क्योंकि मेरे पास पहुंच नहीं है और static_asserts के अलावा बेहतर त्रुटि संदेश हैं)।
समझाते हुए क्यों मदद मिल सकती है (एसएफआईएनएई जांच अधिभार रिज़ॉल्यूशन के दौरान की जानी चाहिए; हर कंपाइलर को संकलित करने के लिए प्रत्येक कंपाइलर को मजबूर करना और यह निर्धारित करने से पहले कि क्या ओवरलोड लोड है, दोनों संकलक लेखकों के लिए कठिन होगा, और परिणाम हो सकता है आश्चर्यजनक व्यवहार में (मैंने 'शून्य *' को 'टी *' से अधिक पसंद किया क्योंकि आपके 'टी *' कोड में एक बग है जिसमें कोड 2 स्तरों में गहरा घोंसला गलती है)। SFINAE चेक एक समझौता है, और यहां तक कि एमएसवीसी भी उन पर * हार्ड * गिर जाता है। – Yakk