I'm trying to replicate a template I've used before with a member function, and it isn't going very well. The basic form of the function is
template<class T>
T Convert( HRESULT (*Foo)(T*))
{
T temp;
Foo(&temp); //Throw if HRESULT is a failure
return temp;
}
HRESULT Converter(UINT* val)
{
*val = 1;
return S_OK;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << Convert<UINT>(Converter) << std::endl;
return 0;
}
For the life of me, I can't get this to work with a member variable. I've read up on their syntax, and I can't seem to figure out how 开发者_如何学Pythonto make it work with templates.
The class would be something similar to
class TestClass
{
HRESULT Converter(UINT* val)
{
*val = 1;
return S_OK;
}
}
TestClass
is stateless. So why do you want to pass a non-static member function? If in the real code you need access to non-static members, you also need to pass the object along
template<class T, class C>
T Convert( HRESULT (C::*Foo)(T*), C c)
{
T temp;
(c.*Foo)(&temp); //Throw if HRESULT is a failure
return temp;
}
You can then call it like the following, assuming the member function is made public
TestClass c;
Convert(&TestClass::Converter, c);
If the class is heavy-weight or if the function changes its object during execution, you may decide to pass the object to Convert
by reference.
Here's the implementation using std::tr1::function.
#include <stdlib.h>
#include <functional>
#include <iostream>
#include <winerror.h>
#include <wtypes.h>
using std::tr1::bind;
using std::tr1::function;
template <typename T>
T Convert(function<HRESULT (T*)> Converter)
{
T temp;
Converter(&temp);
return temp;
}
HRESULT Converter(UINT* val)
{
*val = 1;
return S_OK;
}
class TestClass
{
public:
HRESULT Converter(UINT* val)
{
*val = 2;
return S_OK;
}
};
int main()
{
using namespace std::tr1::placeholders;
std::cout << Convert<UINT>(Converter) << std::endl;
TestClass converter;
std::cout << Convert<UINT>(bind(&TestClass::Converter, converter, _1)) << std::endl;
return EXIT_SUCCESS;
}
精彩评论