以下简化代码无法在VS2013编译:可能ADL错误2013
#include <cmath>
namespace mine
{
template <typename A>
struct Base
{
double value() const { return static_cast<const A&>(*this).value(); }
};
struct Derived : Base <Derived>
{
Derived(double x) : m_val(x) {}
double value() const { return m_val; }
double m_val;
};
template <typename A>
bool isnan(const Base<A>& x) { return ::isnan(x.value()); }
struct ItWorks
{
double value() const { return 3.14; }
};
bool isnan(ItWorks t) { return ::isnan(t.value()); }
}
int main()
{
mine::Derived d(2.0);
bool b = isnan(d); // this one fails in VS2013
mine::ItWorks t;
bool bb = isnan(t); // this one works
return 0;
}
的错误是:
c:\program files (x86)\microsoft visual studio 12.0\vc\include\math.h(425): error C2665: 'fpclassify' : none of the 3 overloads could convert all the argument types
could be 'int fpclassify(long double)'
or 'int fpclassify(double)'
or 'int fpclassify(float)'
while trying to match the argument list '(mine::Derived)'
我期待那ADL会踢打电话时在mine::Derived
上调用,但由于某种原因,VS2013正试图从全局命名空间调用isnan()
模板函数。
当然,如果我叫直接一切正常,但因为我需要调用isnan()
在模板方面,我可能会得到一个double
或mine::CRTP
派生的任何类,这并不解决我的问题。使用CRTP一个简单的结构不:
它必须与模板扣除一定的相互作用,因为一切都按预期mine::ItWorks
。
但是,gcc 5.1.0和clang 3.5.1都认同我并正确地编译了代码。这看起来像一个VS2013的bug ...
任何想法? 谢谢!
它*必须*是与模板演绎相关的东西,因为如果我在名称空间'mine'中添加一个重载'bool isnan(const Derived&x)',那么一切都可以工作。 – dats
为了清楚起见,为* every *函数和* from'mine :: CRTP'派生的每个*类添加重载是*不是一个可行的解决方案,因为有许多函数和许多派生类... :( – dats