Reputation: 1014
I'm not exactly sure how to word this question so I'll just use an example.
I have a class that takes some template parameters to call a member function of a class:
template<typename T, int V, void (T::*F)(int)>
struct CallFunction
{
CallFunction()
{
T t;
(t.*F)(V);
}
};
And I have a class:
struct TestClass
{
void TestFunc( int x ) { std::cout << "Value is: " << x << std::endl; }
};
I then invoke the CallFunction class:
int main()
{
CallFunction<TestClass, 5, &TestClass::TestFunc> cf;
}
As expected this is printed:
Value is: 5
Now I decide that I want to add a layer between the template parameters and CallFunction. Rather than provide each template parameter separately to CallFunction I want to create a "Description" class that provides the parameters. So I try something like this:
template<typename D>
struct CallFunctionWithDescription
{
CallFunctionWithDescription()
{
typename D::T t;
(t.*typename D::F)(typename D::V);
}
};
template<typename DT, int DV, void (DT::*DF)(int)>
struct Description
{
typedef DT T; // OK
static const int V = DV; // OK
static const void (T::*F)(int) = DF; // VC++ error C2864!
};
struct TestClass
{
void TestFunc( int x ) { std::cout << "Value is: " << x << std::endl; }
};
int main()
{
typedef Description<TestClass, 5, &TestClass::TestFunc> TestClassDescription;
CallFunctionWithDescription<TestClassDescription> cfd;
}
Not surprisingly this results in: "error C2864: 'Description::F' : only static const integral data members can be initialized within a class".
Is there any mechanism by which I can get a function pointer template parameter into CallFunctionWithDescription via the single type parameter D, or or am I required to pass the function pointer template argument to CallFunctionWithDescription directly?
Upvotes: 2
Views: 802
Reputation: 300389
You have two solutions:
F
out of the classExample of out of class initialization:
template <typename DT, int DV, void (DT::*DF)(int)>
void (DT::* Description<DT, DV, DF>::F)(int) = DF;
Sorry for this reading really bad, function types are never pretty :x
Example of pattern matching:
// Make reading functions a bit easier
template <typename T> struct identity { typedef T type; };
template<typename DT, int DV, void (DT::*DF)(int)>
struct Description
{
typedef DT T; // OK
static const int V = DV; // OK
};
template <typename DT, int DV, void (DT::*DF)(int)>
typename identity<void (DT::*)(int)>::type function(Description<DT, DV, DF>) {
return DF;
}
In essence, you "deconstruct" the type during pattern matching. It requires a bit more writing that the in-class (static) member.
Upvotes: 1