Pointers to methods & templates problem, C++
There are 2 template classes A and B having 2 private members a1, a2 and b1, b2.
template <typename T>
class A
{
private:
T a1, a2;
public:
T getA1 () const {return a1;}
T getA2 () const {return a2;}
};
template <typename T>
class B
{
private:
T b1, b2;
public:
T getB1 () const {return b1;}
T getB2 () const {return b2;}
};
In the class Test there is a need for 2 pointers pointing to getters.
class Test
{
private:
template <typename T>
static T ( *getFirst ) ();
template <typename T>
static T ( *getSecond ) ();
}
template <typename T>
T ( * Test::getFirst ) () = &A<T>::getA1; //Pointer to getA1, error
template <typename T>
T ( * Test::getSecond ) () = &B<T>::getB2; //Pointer to getB2, error
int main
{
A <double> a;
B <double> b;
double c = a.getFirst + b.getSecond;
}
开发者_如何学Python
T represents fundamental data types... Is it possible implement this code without specialization (i.e. pointers to class template members) or those "pointers" should be specialized? Thanks for any examples...
You're doing illegal things. See this,
template <typename T>
static T ( *getFirst ) ();
Here you're trying to define template function pointer which is illegal in C++.
The C++ Standard says in $14/1,
A template defines a family of classes or functions.
Please note that it does not say "a template defines a family of classes, functions or function pointers". So what you're trying to do is, defining "a family of function pointers" using template, which isn't allowed.
If you want function pointer you can do something like this,
template <class T>
struct A
{
static T (*FunctionPointer)(); //function pointer
};
struct B
{
template <class T>
static T Function(); //static function, not function pointer
};
int (*A<double>::FunctionPointer)() = &B::Function<double>;
Yet better alternative is : use function object. :-)
In short, it's not possible.
First, you cannot declare a pointer to template function, only pointer to a concrete function.
Second, you tried to declare pointer to free function but A::getA1
is a member function with implicit this
argument, so semantic doesn't match.
You can do something like this:
template <typename T>
struct A
{
static T get() { return T() };
};
template <typename T>
struct Holder
{
typedef T(A<T>::*F_ptr)();
static F_ptr f_ptr;
};
template <typename T>
typename Holder<T>::F_ptr Holder<T>::f_ptr = &A<T>::get;
to keep pointer to template function as a member of template class
The line:
template <typename T>
T (*Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error
Has two problems: One is that &A<T>::getA1
is of type T (A::*)()const
but getFirst is of type T (*)()
. These are not compatible because the former is a pointer to a member function, while the latter is not.
The second problem with the line is that the objects created would differ only in their return type. Just like you cannot manually declare both double (A::*getFirst)()const
and char (A::*getFirst)()const
, you also cannot create a template that would automatically declare both of them.
The line:
double c = a.getFirst + b.getSecond;
Has its own set of problems that may or may not relate to the issue at hand.
Sorry for this "non answer." maybe if you talked more about what you are trying to accomplish, rather than how you are trying to accomplish it, we will be able to help.
Your code seems quite confused, so I'm not sure I really understood what you are asking for... here is an adaptation of your example that compiles.
// This is one template class A with two getters
template <typename T>
class A
{
private:
T a1, a2;
public:
T getA1 () const {return a1;}
T getA2 () const {return a2;}
};
// This is another unrelated template class, with two other getters
template <typename T>
class B
{
private:
T b1, b2;
public:
T getB1 () const {return b1;}
T getB2 () const {return b2;}
};
// These are declarations of generic "getFirst" and "getSecond"
template<typename T1, typename T2>
T1 getFirst(const T2& t);
template<class T1, class T2>
T1 getSecond(const T2& t);
// Here I'm specializing getFirst/getSecond for the A template
template<class X>
double getFirst(const A<X>& a) { return a.getA1(); }
template<class X>
double getSecond(const A<X>& a) { return a.getA2(); }
// Here I'm doing the same for the B template
template<class X>
double getFirst(const B<X>& b) { return b.getB1(); }
template<class X>
double getSecond(const B<X>& b) { return b.getB2(); }
// Now I can use getFirst/getSecond with either A or B
int main(int argc, const char *argv[])
{
A<double> a;
B<double> b;
double c = getFirst(a) + getSecond(b);
return 0;
}
精彩评论