2011-02-12 95 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