c++ - Visual Studio 2013 中可能存在的 ADL 错误

标签 c++ gcc visual-studio-2013 argument-dependent-lookup

以下简化代码在 VS2013 下编译失败:

#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)'

我原以为当在 mine::Derived 上调用时,ADL 会开始调用 mine::isnan(),但出于某种原因 VS2013 正在尝试从全局命名空间调用 isnan() 模板函数。

当然,如果我直接调用 mine::isnan() 一切正常,但这并不能解决我的问题,因为我需要调用 isnan()在模板化上下文中,我可能会得到一个 double 或从 mine::CRTP 派生的任何类。

它必须与模板推导有一些交互,因为 mine::ItWorks 的一切都按预期工作:一个简单的结构使用 CRTP。

但是,gcc 5.1.0 和 clang 3.5.1 都同意我的观点,并且可以正确编译代码。这看起来像是一个 VS2013 错误...

有什么想法吗? 谢谢!

最佳答案

据我所见,这似乎不是一个错误。

template<class _Ty> inline __nothrow bool isnan(_Ty _X)

template<typename A> bool isnan(const Base<A>& x)

这些函数将分别解析为

bool isnan(Derived _X)

bool isnan(const Base<Derived>& x)

因此,当 isnan 被赋予 Derived 类型时,它将匹配显式使用 Derived 的函数定义。并且发生错误是因为 fpclassify 无法处理 Derived。

与其尝试覆盖具有模板变量类型的 isnan,不如覆盖 fpclassify 函数。

template <typename A>
int fpclassify(const Base<A>& x)
{
    return ::fpclassify(x.value());
}

然后您的实现将起作用。

评论更新

isnan 可能在全局命名空间(来自 math.h)中,而不仅仅是在导致冲突的 std (cmath) 中。 - Source

关于c++ - Visual Studio 2013 中可能存在的 ADL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30210095/

相关文章:

python - 有没有办法从 Python 调用 C++ 函数?

c++ - 与tbb::task_arena和tbb::task_scheduler_observer链接时出错

TFS 在 Visual Studio 2013 中重命名和删除文件很慢

azure - 下载的许可证不足 Azure/Visual Studio Online 和 Visual Studio 2013

git - 如何配置Visual Studio 2013与Git/SourceTree一起使用

c++ - 在 VS2008 上构建 64 位 Windows 会出现 C2632 错误

c - 为什么我们不能使用预处理器来创建自定义分隔的字符串?

c++ - std::thread::id 的 std::operator== 中的段错误

c - 跨功能的 OpenMP 线程组的持久性

c++ - 为 iOS 编译 OpenFST 时出现转换错误