2013-03-20 124 views
4

我們有很大的計算幾何庫。它的內核存在問題。我們定義了標量taits和自由函數形式的helper accesors,簡單地寫cg::epsilon<T>()而不是cg::scalar_traits<T>::epsilon。但是在vs2008和vs2010下的問題有時候會爭辯說,它不能推導出cg::epsilon<T>T的模板參數。在LWS中的其他編譯器工作正常。解決編譯器問題

簡化版本重現:

namespace cg 
{ 

template<class S> 
S epsilon(); 

template<> 
double epsilon<double>() {return 1;} 
template<> 
float epsilon<float>() {return 1;} 

template<class S> 
bool eq(S a, S b, S eps = cg::epsilon<S>()) 
{ 
    return true; 
} 

} 


int main(int argc, char* argv[]) 
{ 
    cg::eq(0.0, 0.0); 
    cg::eq(0.0f, 0.0f); 
    return 0; 
} 

是否有一些解決方法,使存取工作?

PS:我們使用cg::scalar_traits<S>::epsilon(),幫助,在錯誤的發生,但過多冗長

研究: 即使declarated作爲

template<class S> 
bool eq(S a, S b, S eps = cg::epsilon<double>()) 

編譯器抱怨說,他不能CG演繹S: :小量。

回答

1

我的猜測是編譯器在扣除S時使用默認參數S eps = cg::epsilon<S>()。爲此,需要查看cg::epsilon<S>()的聲明,但目前它還不知道S

一種解決方法是避免的默認值的第三參數,並添加兩個不同的重載:第一有三個參數(abeps和)和第二隻需要兩(ab)。後者得到epscg::epsilon<S>()(此時S已經推導出)和代表呼籲前者如下面的代碼所示:

template<class S> 
bool eq(S a, S b, S eps) 
{ 
    return true; 
} 

template<class S> 
bool eq(S a, S b) 
{ 
    S eps = cg::epsilon<S>(); 
    return eq(a, b, eps); 
} 
+0

你的猜測聲音逼真。但是編寫包裝比使用'cg :: scalar_traits :: epsilon'更糟糕。而且,如果你是對的,爲什麼使用特質不會觸發這個錯誤? – kassak 2013-03-20 10:32:35

+0

看更新,在研究部分。它非常奇怪 – kassak 2013-03-20 10:43:10

+0

@kassak:我也不希望寫封裝,並使用默認參數完全一樣(我相信你的代碼是符合標準的)。編寫包裝是一個不必要的解決方法:-(。我不明白你的意思是「使用特徵不會觸發該錯誤」,但無論如何,我無法確切知道發生了什麼,因爲我看不到Visual Studio的代碼;-)我只能猜測。 – 2013-03-20 10:45:04