Possible Duplicate:
Is it possible to write a C++ template to check for a function's existence?
say there are 2 classes:
struct A{ int GetInt(){ return 10; } };
struct B{ int m; };
I want to use object of type A or B in following function
tempate< typename T >
int GetInt( const T & t )
{
//if it's A, I'll call: return t.GetInt();
//if its' B, I'll call: return t.m;
}
Now, because there are whole bunch of classes, some contain GetInt(), some don't, I don't want to write specialization for each type, I only want to distinguish them by 'containing GetInt() or not in compile time', how should I do this ?
The const qualifier at the end of a member function declaration indicates that the function can be called on objects which are themselves const. const member functions promise not to change the state of any non-mutable data members.
A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.
Declaring a member function with the const keyword specifies that the function is a "read-only" function that doesn't modify the object for which it's called. A constant member function can't modify any non-static data members or call any member functions that aren't constant.
Substitution Failure Is Not An Error, or more compactly, SFINAE
But in your particular case, you don't need SFINAE, virtual members, or anything fancy like that.
You just need an ordinary overloaded function.
int GetInt(A& t) { return t.GetInt(); }
int GetInt(const B& t) { return t.m; }
If there's code that needs to be shared between the different versions, refactor it so that there's a template that calls an overloaded inline function, all type-specific behavior is in the inline function, and all shared behavior is in the template.
For your "I have many many classes" need, SFINAE would look more or less like this:
template<typename T>
int GetInt(const T& t, int (T::*extra)() const = &T::GetInt)
{
return t.GetInt();
}
template<typename T>
auto GetInt(const T& t) -> decltype(t.m)
{
return t.m;
}
EDIT: The reality of SFINAE is much uglier, at least until C++0x comes around. In fact it starts looking just as bad as GMan's answer.
struct A{ int GetInt() const { return 10; } };
struct B{ int m; };
template<typename T, int (T::*extra)() const>
struct has_mfunc
{
typedef int type;
};
template<typename T>
typename has_mfunc<T, &T::GetInt>::type GetInt(const T& t)
{
return t.GetInt();
}
template<typename T, typename U, U (T::*extra)>
struct has_field
{
typedef U type;
};
template<typename T>
typename has_field<T, int, &T::m>::type GetInt(const T& t)
{
return t.m;
}
int main(void)
{
A a;
B b;
b.m = 5;
return GetInt(a) + GetInt(b);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With