简体   繁体   中英

Member function type for template specialization

I am studying the uses of function types in template specialization and I am wondering if there such a thing as a member function type (not talking about member function pointers).

The case that led me to this question is better explained by an exemple...

template< typename FunctionType >
struct Function; // Undefined

// Specialize for functions with 0 parameter...
template< typename ReturnType >
struct Function< ReturnType() > // Notice the unusual syntax here...
{
    // Function pointer that fits the signature of the template...
    ReturnType (*m_pointerToFunction)();
};

// Specialize for functions with 1 parameter...
template< typename ReturnType, typename ParameterType >
struct Function< ReturnType(ParameterType) >
{
    ReturnType (*m_pointerToFunction)(ParameterType);
};

// ... etc up to a certain number of parameter.

// To use this template:
void SomeFunctionTakingNoParameter()
{
}

Function< void() > test;
test.m_pointerToFunction = SomeFunctionTakingNoParameter;

Now what I would like to do is create specialization for member functions. The first thing I tried is:

template< typename ReturnType, typename ObjectType, typename ParameterType >
class Function< ObjectType, ReturnType(ParameterType) >
{
    ReturnType (ObjectType::*m_memberFunctionPointer)(ParameterType);
};

and I use it like this:

struct Object
{
    void DoSomething()
    {
    }
};
Function< Object, void() > function;
function.m_memberFunctionPointer = &Object::DoSomething;

I have to supply 2 arguments to the template (the object type and the signature). I would like to see if there is a way to do it all in one parameter.

The next bit does not compile but I wonder if there is something similar in the language?

template< typename ObjectType, typename ReturnType >
struct Function< ObjectType::ReturnType() >
{
    ReturnType (ObjectType::*m_memberFunctionPointer)();
};
Function< Object::void() > function;
function.m_memberFunctionPointer = &Object::DoSomething;

The syntax void(Object::*)() defines a pointer-to-member-function type. There is no such thing as a member-function type in C++.

In theory you could obtain a member-function type with std::remove_pointer<void(Object::*)()>::type , but this is not valid C++. The documentation for boost::remove_pointer makes a note of this.

The pointer-to-member-function type T (C::*)() is produced by combining a function type T() with a pointer-to-member type TC::* . See this answer for how this combination works.

You can perform this combination with a simple helper template:

template<typename C, typename T>
struct PointerToMember
{
    typedef T C::* Type;
};

typedef PointerToMember<Object, void()>::Type Type; // void(Object::*)()

This may be useful when extending Function to support pointer-to-member.

In C++11 there is decltype , which can give you the type of an expression, eg decltype ObjectType::DoSomething in your case, rather than ObjectType::ReturnType() . The old-school way of doing this is to require that struct Object contain a member type with a specific name, such as ReturnType , and you simply use typename ObjectType::ReturnType (without parentheses).

"There is no such thing as a member-function type in C++."

I guess that pretty much answers my question. Thanks :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM