2011-02-12 98 views
0

有2个模板类A和B有2个私有成员a1,a2和b1,b2。指向方法和模板的指针问题,C++

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;} 

}; 

在类Test中,需要2个指向getter的指针。

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; 
} 

T表示基本数据类型...是否有可能实现这个代码,而专业化(即指针类模板成员)或那些“指针”应为专业?感谢任何例子...

+0

我试图编写一个答案,但失败的原因之一:我不明白你打算用你的类测试。你提供了一个有错误的定义,但是你不会在任何地方使用它。解决这些错误的方法很大程度上取决于您打算如何使用它。下面的一些答案可能对您有用,但为了得到正确的答案,您需要提供一个Test的示例用法。 – 2011-02-12 15:51:16

回答

0

你在做非法的事情。看到这,

template <typename T> 
static T (*getFirst)(); 

在这里,我们试图确定模板函数指针这是在C++中是非法的。

C++标准说,在$ 14/​​1,

模板定义家庭功能的。

请注意,它不“模板定义了一类功能或函数指针的”。所以你要做的是,使用模板定义“一系列函数指针”,这是不允许的。


如果你想要一个函数指针,你可以做这样的事情,

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>; 

但更好的方法是:使用function object。 :-)

+0

好的,谢谢...函数不会是静态的时候,代码如何显示?在这种情况下,我还可以问你一个使用函数对象的简短例子吗? – CrocodileDundee 2011-02-12 20:25:16

0

总之,这是不可能的。

首先,你不能声明一个指向模板函数的指针,只能指向一个具体的函数。 其次,您试图声明指向自由函数的指针,但A::getA1是含有隐含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; 

保持指针模板功能模板类的成员

0

行:

template <typename T> 
T (*Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error 

有两个问题:一个是&A<T>::getA1的类型为T (A::*)()const,但getFirst的类型为T (*)()。这些不兼容,因为前者是指向成员函数的指针,而后者则不是。

该行的第二个问题是创建的对象只会在返回类型上有所不同。就像您无法手动声明double (A::*getFirst)()constchar (A::*getFirst)()const一样,您也无法创建可自动声明它们的模板。

行:

double c = a.getFirst + b.getSecond;

有它自己的一套,可能会或可能不会在手与这个问题有关的问题。

对不起,这个“无答案”。也许如果你更多地谈论你正在努力完成的事情,而不是你如何努力完成它,我们将能够提供帮助。

0

你的代码似乎很混乱,所以我不确定我是否真的明白你在问什么......这是你的编译示例的改编。

// 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; 
} 
+0

一个有趣的解决方案,谢谢。 – CrocodileDundee 2011-02-12 20:25:45