我有大计算几何库。它的内核存在问题。我们有定义标量taits和自由函数形式的辅助加法器,只需编写cg::epsilon<T>()
而不是cg::scalar_traits<T>::epsilon
。但问题是,在vs2008和vs2010下,它有时会争辩说它无法推导T
中cg::epsilon<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()
,这有助于发生错误,但是过于冗长
研究: 甚至声明为
template<class S>
bool eq(S a, S b, S eps = cg::epsilon<double>())
编译器抱怨他不能为cg :: epsilon推断出S.
答案 0 :(得分:1)
我的猜测是编译器在S eps = cg::epsilon<S>()
的推导中使用了默认参数S
。为此,需要查看cg::epsilon<S>()
的声明,但此时它还不知道S
。
解决方法是避免第三个参数的默认值并添加两个不同的重载:第一个需要三个参数(a
,b
和eps
),第二个只需要两个(a
和b
)。后者从eps
获得cg::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);
}