यदि आप f
सभी प्रकार के फ़ंक्शन को कॉल करने में सक्षम होना चाहते हैं getInt
, जिसमें फ़ंक्शन सदस्य हैं , तो बस नहीं X
, आप फ़ंक्शन के लिए 2 ओवरलोड की घोषणा कर सकते हैं f
:
उन प्रकारों के लिए getInt
जिनमें कक्षा सहित सदस्य कार्य होते हैंX
कक्षा सहित अन्य सभी प्रकारों के लिए Y
।
सी ++ 11 / सी ++ 17 समाधान
ध्यान में रखते हुए, आप ऐसा कुछ कर सकते हैं:
#include <iostream>
#include <type_traits>
template <typename, typename = void>
struct has_getInt : std::false_type {};
template <typename T>
struct has_getInt<T, std::void_t<decltype(((T*)nullptr)->getInt())>> : std::is_convertible<decltype(((T*)nullptr)->getInt()), int>
{};
class X {
public:
int getInt(){
return 9;
}
};
class Y {};
template <typename T,
typename std::enable_if<!has_getInt<T>::value, T>::type* = nullptr>
void f(T& v) {
// only for Y
std::cout << "Y" << std::endl;
}
template <typename T,
typename std::enable_if<has_getInt<T>::value, T>::type* = nullptr>
void f(T& v){
// only for X
int i = v.getInt();
std::cout << "X" << std::endl;
}
int main() {
X x;
f(x);
Y y;
f(y);
}
इसे लाइव देखें ।
कृपया ध्यान दें कि std::void_t
C ++ 17 में पेश किया गया है, लेकिन यदि आप C ++ 11 तक सीमित हैं, तो void_t
अपने दम पर लागू करना वास्तव में आसान है :
template <typename...>
using void_t = void;
और यहाँ C ++ 11 संस्करण लाइव है ।
C ++ 20 में हमारे पास क्या है?
C ++ 20 बहुत सारी अच्छी चीजें लाता है और उनमें से एक अवधारणा है । उपरोक्त चीज़ जो C ++ 11 / C ++ 14 / C ++ 17 के लिए मान्य है, C ++ 20 में काफी कम की जा सकती है:
#include <iostream>
#include <concepts>
template<typename T>
concept HasGetInt = requires (T& v) { { v.getInt() } -> std::convertible_to<int>; };
class X {
public:
int getInt(){
return 9;
}
};
class Y {};
template <typename T>
void f(T& v) {
// only for Y
std::cout << "Y" << std::endl;
}
template <HasGetInt T>
void f(T& v){
// only for X
int i = v.getInt();
std::cout << "X" << std::endl;
}
int main() {
X x;
f(x);
Y y;
f(y);
}
इसे लाइव देखें ।
type_info
संरचना में एक समानता तुलना ऑपरेटर है , इसलिएtypeid(T) == typeid(X)
इसे भी काम करना चाहिए।