2010-10-30 54 views
0

我有一個關於模板的問題。我想有一個模板類,包含float或double的數組。模板類的C++投射

我可以編寫一個與之重複的clone()函數。沒問題。但是,我想要另一個名爲cast()的函數在double和float之間來回轉換。這之前已經有所討論,但我不認爲這個問題是一樣的:

stackoverflow.com/questions/714213/c-template-casting

我的問題是一個編譯器錯誤,而不是一個連接錯誤。錯誤信息是:

main.cpp: In function `void caster()': 
main.cpp:63: error: expected primary-expression before "double" 
main.cpp:63: error: expected `;' before "double" 
main.cpp:64: error: expected primary-expression before "float" 
main.cpp:64: error: expected `;' before "float" 
main.cpp:65: error: expected primary-expression before '>' token 
main.cpp:65: error: expected primary-expression before ')' token 

我傾倒了下面的代碼。第63,64和65行是我在這裏評論「錯誤在這裏」的地方。我的編譯器是GNU C++版本3.4.5 20051201(Red Hat 3.4.5-2)(x86_64-redhat-linux)編譯的GNU C版本3.4.5 20051201(Red Hat 3.4.5)(x86_64-redhat-linux) -2)」。

一些谷歌搜索後,原來已經有人遇到過這個問題:

gcc.gnu.org/ml/gcc-help/2006-04/msg00022.html

這裏有一個解決方案:

gcc.gnu.org/ml/gcc-help/2006-04/msg00023.html

但是當樓主問的到爲什麼有用,答案不是很清楚:

gcc.gnu.org/ml/gcc-help/2006-04/msg00025.html

不幸的是,這個鏈接已經死了,我沒有第三版的Stroustrup。現在,我有我的修復程序,我的代碼工作。但是,Stackoverflow,爲什麼它工作?


#include <stdio.h> 

// =================== This would be the header =================== 
template <class T> 
class foo 
{ 
public: 
      foo(const T val) {d_data = new double; *d_data = val;} 
    virtual ~foo() {delete d_data;}; 

    foo* clone() const; 

    template<class U> 
    foo<U>* cast() const; 

private: 
    double *d_data; 
}; 

// =================== This would be the implementation of the class =================== 
template<class T> 
foo<T>* foo<T>::clone() const 
{ 
    return new foo<T>(*d_data); 
} 

template<class T> 
template<class U> 
foo<U>* foo<T>::cast() const 
{ 
    return new foo<U>(*d_data); 
} 

template class foo<float>; 
template class foo<double>; 

template foo<float>* foo<float>::cast() const; 
template foo<float>* foo<double>::cast() const; 
template foo<double>* foo<float>::cast() const; 
template foo<double>* foo<double>::cast() const; 

// =================== Using the class =================== 
template <class T> 
void caster() 
{ 
    foo<double> *f1 = NULL; 
    foo<float> *f2 = NULL; 
    foo<T>  *f3 = NULL; 

    // I am looking at something that compiles 
    // I don't care about linking for now 
    // This will crash at runtime because of 
    // NULL, but that's just an example 

    f1->cast<double>(); // compiler OK 
    f1->cast<float>(); // compiler OK 
    f1->cast<T>();  // compiler OK 

    f2->cast<double>(); // compiler OK 
    f2->cast<float>(); // compiler OK 
    f2->cast<T>();  // compiler OK 

    f3->cast<double>(); // Error here 
    f3->cast<float>(); // Error here 
    f3->cast<T>();  // Error here 

    f3->foo<T>::template cast<double>(); // It works! 
    f3->foo<T>::template cast<float>(); // It works! 
    f3->foo<T>::template cast<T>();  // It works! 
} 

int main(int argc, char **argv) 
{ 
    return 0; 
} 
+0

對不起,我沒有足夠的聲望點來發布URL – 2010-10-30 00:44:56

+0

我鏈接了你的網址。 – Doug 2010-10-30 01:23:37

回答

4
f3->cast<double>(); // Error here 

在這一行,編譯器不知道是否在<f3->cast的解釋是:模板參數開始,如果它是一個小於比較操作。

要明確指定它代表模板參數的開始。正確的方法是

f3->template cast<double>(); 

總之,.template符號(以及類似的符號如->template)只應使用模板內且僅當他們遵循的東西,取決於模板參數(如表達f3這取決於模板參數T