解决编译器错误

时间:2013-03-20 10:05:50

标签: c++ visual-studio templates compiler-bug

我有大计算几何库。它的内核存在问题。我们有定义标量taits和自由函数形式的辅助加法器,只需编写cg::epsilon<T>()而不是cg::scalar_traits<T>::epsilon。但问题是,在vs2008和vs2010下,它有时会争辩说它无法推导Tcg::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.

1 个答案:

答案 0 :(得分:1)

我的猜测是编译器在S eps = cg::epsilon<S>()的推导中使用了默认参数S。为此,需要查看cg::epsilon<S>()的声明,但此时它还不知道S

解决方法是避免第三个参数的默认值并添加两个不同的重载:第一个需要三个参数(abeps),第二个只需要两个(ab)。后者从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);
}