For example:
template <typename T>
void foo(T ptr)
{
typedef GET_CLASS_TYPE(T) ClassT;
typedef GET_VALUE_TYPE(T) ValueT;
// ...
}
struct Bar
{
int var;
};
foo(&Bar::var);
Inside the last function call to foo(...)
, ClassT
should be Bar
and ValueT
should be int
.
How can I do this with plain C++ (can't use C++11 features), or boost?
Not aware of any out-of-the-box Boost type trait to do this, but the same can be written by yourself using template specialization:
template<typename T>
struct member_pointer_class;
template<typename Class, typename Value>
struct member_pointer_class<Value Class::*>
{
typedef Class type;
};
template<typename T>
struct member_pointer_value;
template<typename Class, typename Value>
struct member_pointer_value<Value Class::*>
{
typedef Value type;
};
// TEST
#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>
struct Bar
{
int var;
};
template <typename T>
void foo(T ptr)
{
// test the code
typedef typename member_pointer_class<T>::type ClassT;
typedef typename member_pointer_value<T>::type ValueT;
BOOST_STATIC_ASSERT_MSG((boost::is_same<ClassT, Bar>::value), "member_pointer_class is the same as Bar");
BOOST_STATIC_ASSERT_MSG((boost::is_same<ValueT, int>::value), "member_pointer_value is the same as int");
}
int main()
{
foo(&Bar::var);
}
Explanation:
Using template deduction we extract the interesting types of the member pointer - the typedefs member_pointer_class<T>::type
and member_pointer_value<T>::type
are defined to the appropriate types. typename
is required for disambiguation in templates. The code can be also used for pointer to member functions.
If the type is not a pointer to member, the member_pointer_class<T>::type
gives a compiler error.
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