简体   繁体   English

MSVC C ++ ADL错误?

[英]MSVC C++ ADL bug?

This code works fine with GCC and Clang. 这段代码可以在GCC和Clang上正常工作。 It works fine in MSVC when using a custom type instead of std::chrono::duration. 当使用自定义类型而不是std :: chrono :: duration时,它在MSVC中工作正常。 It works fine when using an operator+ over operator* . 当使用operator+ over operator*时,它可以正常工作。 It works fine with MSVC pre 2018 instead of 2017/2015. 它可以在2018年之前的MSVC而不是2017/2015之前正常工作。

Am I missing anything obvious, or is this just a bug in MSVC? 我是否遗漏了任何明显的内容,或者这仅仅是MSVC中的错误? https://godbolt.org/z/EUWV7e https://godbolt.org/z/EUWV7e

For completeness, here is the test case from the above link: 为了完整起见,以下是上述链接中的测试用例:

#include <chrono>

namespace A {
    class Foo {
    public:
        int mCount;
        constexpr explicit Foo(int count) : mCount( count ) {}
    };

    template<class Rep, class Period>
    inline Foo
    operator*(const Foo foo1, const std::chrono::duration<Rep, Period> duration) {
        return Foo(foo1.mCount * duration.count());
    }

    // For testing purposes, this is identical to operator* above.
    template<class Rep, class Period>
    inline Foo
    operator+(const Foo foo1, const std::chrono::duration<Rep, Period> duration) {
        return Foo(foo1.mCount * duration.count());
    }
}

int main() {
    A::Foo foo1(50);

    // This fails to compile for some reason?  Changing the '*' to a '+' works fine however.
    auto foo2 = foo1 * std::chrono::minutes(15);
    return foo2.mCount;
}

from <chrono> : 来自<chrono>

template<class _Rep1,
    class _Rep2,
    class _Period2> inline
    constexpr typename enable_if<is_convertible<_Rep1,
        typename common_type<_Rep1, _Rep2>::type>::value,
        duration<typename common_type<_Rep1, _Rep2>::type, _Period2> >::type
        operator*(
            const _Rep1& _Left,
            const duration<_Rep2, _Period2>& _Right) ...

Note that since std::chrono::minutes is duration<int, ratio<60>> -- _Rep2 is int . 请注意,由于std::chrono::minutesduration<int, ratio<60>> _Rep2int Now common_type<_Rep1, _Rep2> expands to (see <type_traits> ): 现在common_type<_Rep1, _Rep2>扩展为(请参见<type_traits> ):

    struct common_type  // <Foo, int>
    {   // type is common type of Foo and int for two arguments
        typedef typename decay<
            decltype(false ? declval<Foo>() : declval<int>())
        >::type type;
    };

Error you observe is conditional operator complaint that somehow isn't "intercepted" by SFINAE. 您观察到的错误是有条件的操作员投诉,表明SFINAE并未“拦截”。 If you remove explicit from Foo's ctor -- it'll go away. 如果从Foo的ctor中删除explicit ,它将消失。

I am not intimately familiar with finer points of SFINAE behavior, but cppreference.com has curious note: 我对SFINAE行为的细节并不十分熟悉,但是cppreference.com有一个奇怪的提示:

Only the failures in the types and expressions in the immediate context of the function type or its template parameter types or its explicit specifier (since C++20) are SFINAE errors. 只有函数类型或其模板参数类型或其显式说明符(自C ++ 20起)的直接上下文中的类型和表达式失败才是SFINAE错误。 If the evaluation of a substituted type/expression causes a side-effect such as instantiation of some template specialization, generation of an implicitly-defined member function, etc, errors in those side-effects are treated as hard errors. 如果对替换类型/表达式的求值引起副作用,例如某些模板专门化的实例化,隐式定义的成员函数的生成等,则将这些副作用中的错误视为硬错误。

I am not sure this applies to your case... If it does -- then MS compiler is right, but their std lib has a problem. 我不确定这是否适用于您的情况...如果确实如此-那么MS编译器是正确的,但是其std lib有问题。 If it doesn't -- then it is probably an issue in compiler. 如果不是,则可能是编译器中的一个问题。

Edit: apparently MS had problems with SFINAE for a while... 编辑:显然MS有一段时间SFINAE 问题 ...

I've reported this to the MSVC team at https://developercommunity.visualstudio.com/content/problem/381899/adl-sfinae-bug-in-mvc20152017-when-using-stdchrono.html and they've confirmed it is a bug in MSVC, and has been fixed in the latest release of MSVC2017. 我已在https://developercommunity.visualstudio.com/content/problem/381899/adl-sfinae-bug-in-mvc20152017-when-using-stdchrono.html向MSVC小组报告了此消息,并且他们确认这是MSVC中的一个错误,已在最新版本的MSVC2017中修复。 Thanks for the discussions! 感谢您的讨论!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM