c++ - MSVC C++ ADL 错误?

标签 c++ visual-c++ argument-dependent-lookup

此代码适用于 GCC 和 Clang。当使用自定义类型而不是 std::chrono::duration 时,它在 MSVC 中工作正常。在 operator* 上使用 operator+ 时效果很好。它适用于 MSVC pre 2018 而不是 2017/2015。

我是否遗漏了任何明显的东西,或者这只是 MSVC 中的一个错误? https://godbolt.org/z/EUWV7e

为了完整性,这里是来自上面链接的测试用例:

#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;
}

最佳答案

来自 <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) ...

注意自 std::chrono::minutesduration<int, ratio<60>> -- _Rep2int .现在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;
    };

您观察到的错误是有条件的运算符(operator)投诉,不知何故未被 SFINAE“拦截”。如果删除 explicit来自 Foo 的 ctor——它会消失。

我不是很熟悉 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. 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.

我不确定这是否适用于您的情况...如果适用——那么 MS 编译器是正确的,但他们的标准库有问题。如果不是——那么它可能是编译器中的一个问题。

编辑:显然 MS 有 problems在 SFINAE 呆了一段时间...

关于c++ - MSVC C++ ADL 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53289393/

相关文章:

c++ - 使用 wxNotebook 创建选项卡闪烁效果(如 IM 程序)

c++ - 如果最终用户需要链接到调试 CRT,分发 SDK 的最佳方式是什么?

javascript - 在 C++ 中将 ostream 分配给数据类型字符串

C++无重复数随机数生成器

visual-c++ - cvFindContours 总是返回 0 - OpenCV

c++ - const 正确性和成员指针

c++ - 内部编译器错误(CL版本:14.27.29110)

c++ - 为类模板的特定嵌套类实现非成员泛型函数

c++ - 什么是 "Argument-Dependent Lookup"(又名 ADL,或 "Koenig Lookup")?

c++ - 为什么ADL找不到函数模板?