2013-03-20 225 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